xref: /illumos-gate/usr/src/common/crypto/blowfish/blowfish_impl.c (revision fb2a9bae0030340ad72b9c26ba1ffee2ee3cafec)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Blowfish encryption/decryption and keyschedule code.
28  */
29 
30 #include <sys/types.h>
31 #include <sys/systm.h>
32 #include <sys/ddi.h>
33 #include <sys/sysmacros.h>
34 #include <sys/strsun.h>
35 #include <sys/note.h>
36 #include <sys/byteorder.h>
37 #include <sys/crypto/spi.h>
38 #include <modes/modes.h>
39 #include <sys/crypto/common.h>
40 #include "blowfish_impl.h"
41 
42 #ifdef _KERNEL
43 
44 #define	BLOWFISH_ASSERT(x)	ASSERT(x)
45 
46 #else /* !_KERNEL */
47 
48 #include <strings.h>
49 #include <stdlib.h>
50 #define	BLOWFISH_ASSERT(x)
51 #endif /* _KERNEL */
52 
53 #if defined(__i386) || defined(__amd64)
54 #include <sys/byteorder.h>
55 #define	UNALIGNED_POINTERS_PERMITTED
56 #endif
57 
58 /* EXPORT DELETE START */
59 
60 /*
61  * Blowfish initial P box and S boxes, derived from the hex digits of PI.
62  *
63  * NOTE:  S boxes are placed into one large array.
64  */
65 static const uint32_t init_P[] = {
66 	0x243f6a88U, 0x85a308d3U, 0x13198a2eU,
67 	0x03707344U, 0xa4093822U, 0x299f31d0U,
68 	0x082efa98U, 0xec4e6c89U, 0x452821e6U,
69 	0x38d01377U, 0xbe5466cfU, 0x34e90c6cU,
70 	0xc0ac29b7U, 0xc97c50ddU, 0x3f84d5b5U,
71 	0xb5470917U, 0x9216d5d9U, 0x8979fb1bU
72 };
73 
74 static const uint32_t init_S[] = {
75 	/* S-Box 0. */
76 	0xd1310ba6U, 0x98dfb5acU, 0x2ffd72dbU, 0xd01adfb7U,
77 	0xb8e1afedU, 0x6a267e96U, 0xba7c9045U, 0xf12c7f99U,
78 	0x24a19947U, 0xb3916cf7U, 0x0801f2e2U, 0x858efc16U,
79 	0x636920d8U, 0x71574e69U, 0xa458fea3U, 0xf4933d7eU,
80 	0x0d95748fU, 0x728eb658U, 0x718bcd58U, 0x82154aeeU,
81 	0x7b54a41dU, 0xc25a59b5U, 0x9c30d539U, 0x2af26013U,
82 	0xc5d1b023U, 0x286085f0U, 0xca417918U, 0xb8db38efU,
83 	0x8e79dcb0U, 0x603a180eU, 0x6c9e0e8bU, 0xb01e8a3eU,
84 	0xd71577c1U, 0xbd314b27U, 0x78af2fdaU, 0x55605c60U,
85 	0xe65525f3U, 0xaa55ab94U, 0x57489862U, 0x63e81440U,
86 	0x55ca396aU, 0x2aab10b6U, 0xb4cc5c34U, 0x1141e8ceU,
87 	0xa15486afU, 0x7c72e993U, 0xb3ee1411U, 0x636fbc2aU,
88 	0x2ba9c55dU, 0x741831f6U, 0xce5c3e16U, 0x9b87931eU,
89 	0xafd6ba33U, 0x6c24cf5cU, 0x7a325381U, 0x28958677U,
90 	0x3b8f4898U, 0x6b4bb9afU, 0xc4bfe81bU, 0x66282193U,
91 	0x61d809ccU, 0xfb21a991U, 0x487cac60U, 0x5dec8032U,
92 	0xef845d5dU, 0xe98575b1U, 0xdc262302U, 0xeb651b88U,
93 	0x23893e81U, 0xd396acc5U, 0x0f6d6ff3U, 0x83f44239U,
94 	0x2e0b4482U, 0xa4842004U, 0x69c8f04aU, 0x9e1f9b5eU,
95 	0x21c66842U, 0xf6e96c9aU, 0x670c9c61U, 0xabd388f0U,
96 	0x6a51a0d2U, 0xd8542f68U, 0x960fa728U, 0xab5133a3U,
97 	0x6eef0b6cU, 0x137a3be4U, 0xba3bf050U, 0x7efb2a98U,
98 	0xa1f1651dU, 0x39af0176U, 0x66ca593eU, 0x82430e88U,
99 	0x8cee8619U, 0x456f9fb4U, 0x7d84a5c3U, 0x3b8b5ebeU,
100 	0xe06f75d8U, 0x85c12073U, 0x401a449fU, 0x56c16aa6U,
101 	0x4ed3aa62U, 0x363f7706U, 0x1bfedf72U, 0x429b023dU,
102 	0x37d0d724U, 0xd00a1248U, 0xdb0fead3U, 0x49f1c09bU,
103 	0x075372c9U, 0x80991b7bU, 0x25d479d8U, 0xf6e8def7U,
104 	0xe3fe501aU, 0xb6794c3bU, 0x976ce0bdU, 0x04c006baU,
105 	0xc1a94fb6U, 0x409f60c4U, 0x5e5c9ec2U, 0x196a2463U,
106 	0x68fb6fafU, 0x3e6c53b5U, 0x1339b2ebU, 0x3b52ec6fU,
107 	0x6dfc511fU, 0x9b30952cU, 0xcc814544U, 0xaf5ebd09U,
108 	0xbee3d004U, 0xde334afdU, 0x660f2807U, 0x192e4bb3U,
109 	0xc0cba857U, 0x45c8740fU, 0xd20b5f39U, 0xb9d3fbdbU,
110 	0x5579c0bdU, 0x1a60320aU, 0xd6a100c6U, 0x402c7279U,
111 	0x679f25feU, 0xfb1fa3ccU, 0x8ea5e9f8U, 0xdb3222f8U,
112 	0x3c7516dfU, 0xfd616b15U, 0x2f501ec8U, 0xad0552abU,
113 	0x323db5faU, 0xfd238760U, 0x53317b48U, 0x3e00df82U,
114 	0x9e5c57bbU, 0xca6f8ca0U, 0x1a87562eU, 0xdf1769dbU,
115 	0xd542a8f6U, 0x287effc3U, 0xac6732c6U, 0x8c4f5573U,
116 	0x695b27b0U, 0xbbca58c8U, 0xe1ffa35dU, 0xb8f011a0U,
117 	0x10fa3d98U, 0xfd2183b8U, 0x4afcb56cU, 0x2dd1d35bU,
118 	0x9a53e479U, 0xb6f84565U, 0xd28e49bcU, 0x4bfb9790U,
119 	0xe1ddf2daU, 0xa4cb7e33U, 0x62fb1341U, 0xcee4c6e8U,
120 	0xef20cadaU, 0x36774c01U, 0xd07e9efeU, 0x2bf11fb4U,
121 	0x95dbda4dU, 0xae909198U, 0xeaad8e71U, 0x6b93d5a0U,
122 	0xd08ed1d0U, 0xafc725e0U, 0x8e3c5b2fU, 0x8e7594b7U,
123 	0x8ff6e2fbU, 0xf2122b64U, 0x8888b812U, 0x900df01cU,
124 	0x4fad5ea0U, 0x688fc31cU, 0xd1cff191U, 0xb3a8c1adU,
125 	0x2f2f2218U, 0xbe0e1777U, 0xea752dfeU, 0x8b021fa1U,
126 	0xe5a0cc0fU, 0xb56f74e8U, 0x18acf3d6U, 0xce89e299U,
127 	0xb4a84fe0U, 0xfd13e0b7U, 0x7cc43b81U, 0xd2ada8d9U,
128 	0x165fa266U, 0x80957705U, 0x93cc7314U, 0x211a1477U,
129 	0xe6ad2065U, 0x77b5fa86U, 0xc75442f5U, 0xfb9d35cfU,
130 	0xebcdaf0cU, 0x7b3e89a0U, 0xd6411bd3U, 0xae1e7e49U,
131 	0x00250e2dU, 0x2071b35eU, 0x226800bbU, 0x57b8e0afU,
132 	0x2464369bU, 0xf009b91eU, 0x5563911dU, 0x59dfa6aaU,
133 	0x78c14389U, 0xd95a537fU, 0x207d5ba2U, 0x02e5b9c5U,
134 	0x83260376U, 0x6295cfa9U, 0x11c81968U, 0x4e734a41U,
135 	0xb3472dcaU, 0x7b14a94aU, 0x1b510052U, 0x9a532915U,
136 	0xd60f573fU, 0xbc9bc6e4U, 0x2b60a476U, 0x81e67400U,
137 	0x08ba6fb5U, 0x571be91fU, 0xf296ec6bU, 0x2a0dd915U,
138 	0xb6636521U, 0xe7b9f9b6U, 0xff34052eU, 0xc5855664U,
139 	0x53b02d5dU, 0xa99f8fa1U, 0x08ba4799U, 0x6e85076aU,
140 
141 	/* S-Box 1. */
142 	0x4b7a70e9U, 0xb5b32944U, 0xdb75092eU, 0xc4192623U,
143 	0xad6ea6b0U, 0x49a7df7dU, 0x9cee60b8U, 0x8fedb266U,
144 	0xecaa8c71U, 0x699a17ffU, 0x5664526cU, 0xc2b19ee1U,
145 	0x193602a5U, 0x75094c29U, 0xa0591340U, 0xe4183a3eU,
146 	0x3f54989aU, 0x5b429d65U, 0x6b8fe4d6U, 0x99f73fd6U,
147 	0xa1d29c07U, 0xefe830f5U, 0x4d2d38e6U, 0xf0255dc1U,
148 	0x4cdd2086U, 0x8470eb26U, 0x6382e9c6U, 0x021ecc5eU,
149 	0x09686b3fU, 0x3ebaefc9U, 0x3c971814U, 0x6b6a70a1U,
150 	0x687f3584U, 0x52a0e286U, 0xb79c5305U, 0xaa500737U,
151 	0x3e07841cU, 0x7fdeae5cU, 0x8e7d44ecU, 0x5716f2b8U,
152 	0xb03ada37U, 0xf0500c0dU, 0xf01c1f04U, 0x0200b3ffU,
153 	0xae0cf51aU, 0x3cb574b2U, 0x25837a58U, 0xdc0921bdU,
154 	0xd19113f9U, 0x7ca92ff6U, 0x94324773U, 0x22f54701U,
155 	0x3ae5e581U, 0x37c2dadcU, 0xc8b57634U, 0x9af3dda7U,
156 	0xa9446146U, 0x0fd0030eU, 0xecc8c73eU, 0xa4751e41U,
157 	0xe238cd99U, 0x3bea0e2fU, 0x3280bba1U, 0x183eb331U,
158 	0x4e548b38U, 0x4f6db908U, 0x6f420d03U, 0xf60a04bfU,
159 	0x2cb81290U, 0x24977c79U, 0x5679b072U, 0xbcaf89afU,
160 	0xde9a771fU, 0xd9930810U, 0xb38bae12U, 0xdccf3f2eU,
161 	0x5512721fU, 0x2e6b7124U, 0x501adde6U, 0x9f84cd87U,
162 	0x7a584718U, 0x7408da17U, 0xbc9f9abcU, 0xe94b7d8cU,
163 	0xec7aec3aU, 0xdb851dfaU, 0x63094366U, 0xc464c3d2U,
164 	0xef1c1847U, 0x3215d908U, 0xdd433b37U, 0x24c2ba16U,
165 	0x12a14d43U, 0x2a65c451U, 0x50940002U, 0x133ae4ddU,
166 	0x71dff89eU, 0x10314e55U, 0x81ac77d6U, 0x5f11199bU,
167 	0x043556f1U, 0xd7a3c76bU, 0x3c11183bU, 0x5924a509U,
168 	0xf28fe6edU, 0x97f1fbfaU, 0x9ebabf2cU, 0x1e153c6eU,
169 	0x86e34570U, 0xeae96fb1U, 0x860e5e0aU, 0x5a3e2ab3U,
170 	0x771fe71cU, 0x4e3d06faU, 0x2965dcb9U, 0x99e71d0fU,
171 	0x803e89d6U, 0x5266c825U, 0x2e4cc978U, 0x9c10b36aU,
172 	0xc6150ebaU, 0x94e2ea78U, 0xa5fc3c53U, 0x1e0a2df4U,
173 	0xf2f74ea7U, 0x361d2b3dU, 0x1939260fU, 0x19c27960U,
174 	0x5223a708U, 0xf71312b6U, 0xebadfe6eU, 0xeac31f66U,
175 	0xe3bc4595U, 0xa67bc883U, 0xb17f37d1U, 0x018cff28U,
176 	0xc332ddefU, 0xbe6c5aa5U, 0x65582185U, 0x68ab9802U,
177 	0xeecea50fU, 0xdb2f953bU, 0x2aef7dadU, 0x5b6e2f84U,
178 	0x1521b628U, 0x29076170U, 0xecdd4775U, 0x619f1510U,
179 	0x13cca830U, 0xeb61bd96U, 0x0334fe1eU, 0xaa0363cfU,
180 	0xb5735c90U, 0x4c70a239U, 0xd59e9e0bU, 0xcbaade14U,
181 	0xeecc86bcU, 0x60622ca7U, 0x9cab5cabU, 0xb2f3846eU,
182 	0x648b1eafU, 0x19bdf0caU, 0xa02369b9U, 0x655abb50U,
183 	0x40685a32U, 0x3c2ab4b3U, 0x319ee9d5U, 0xc021b8f7U,
184 	0x9b540b19U, 0x875fa099U, 0x95f7997eU, 0x623d7da8U,
185 	0xf837889aU, 0x97e32d77U, 0x11ed935fU, 0x16681281U,
186 	0x0e358829U, 0xc7e61fd6U, 0x96dedfa1U, 0x7858ba99U,
187 	0x57f584a5U, 0x1b227263U, 0x9b83c3ffU, 0x1ac24696U,
188 	0xcdb30aebU, 0x532e3054U, 0x8fd948e4U, 0x6dbc3128U,
189 	0x58ebf2efU, 0x34c6ffeaU, 0xfe28ed61U, 0xee7c3c73U,
190 	0x5d4a14d9U, 0xe864b7e3U, 0x42105d14U, 0x203e13e0U,
191 	0x45eee2b6U, 0xa3aaabeaU, 0xdb6c4f15U, 0xfacb4fd0U,
192 	0xc742f442U, 0xef6abbb5U, 0x654f3b1dU, 0x41cd2105U,
193 	0xd81e799eU, 0x86854dc7U, 0xe44b476aU, 0x3d816250U,
194 	0xcf62a1f2U, 0x5b8d2646U, 0xfc8883a0U, 0xc1c7b6a3U,
195 	0x7f1524c3U, 0x69cb7492U, 0x47848a0bU, 0x5692b285U,
196 	0x095bbf00U, 0xad19489dU, 0x1462b174U, 0x23820e00U,
197 	0x58428d2aU, 0x0c55f5eaU, 0x1dadf43eU, 0x233f7061U,
198 	0x3372f092U, 0x8d937e41U, 0xd65fecf1U, 0x6c223bdbU,
199 	0x7cde3759U, 0xcbee7460U, 0x4085f2a7U, 0xce77326eU,
200 	0xa6078084U, 0x19f8509eU, 0xe8efd855U, 0x61d99735U,
201 	0xa969a7aaU, 0xc50c06c2U, 0x5a04abfcU, 0x800bcadcU,
202 	0x9e447a2eU, 0xc3453484U, 0xfdd56705U, 0x0e1e9ec9U,
203 	0xdb73dbd3U, 0x105588cdU, 0x675fda79U, 0xe3674340U,
204 	0xc5c43465U, 0x713e38d8U, 0x3d28f89eU, 0xf16dff20U,
205 	0x153e21e7U, 0x8fb03d4aU, 0xe6e39f2bU, 0xdb83adf7U,
206 
207 	/* S-Box 2. */
208 	0xe93d5a68U, 0x948140f7U, 0xf64c261cU, 0x94692934U,
209 	0x411520f7U, 0x7602d4f7U, 0xbcf46b2eU, 0xd4a20068U,
210 	0xd4082471U, 0x3320f46aU, 0x43b7d4b7U, 0x500061afU,
211 	0x1e39f62eU, 0x97244546U, 0x14214f74U, 0xbf8b8840U,
212 	0x4d95fc1dU, 0x96b591afU, 0x70f4ddd3U, 0x66a02f45U,
213 	0xbfbc09ecU, 0x03bd9785U, 0x7fac6dd0U, 0x31cb8504U,
214 	0x96eb27b3U, 0x55fd3941U, 0xda2547e6U, 0xabca0a9aU,
215 	0x28507825U, 0x530429f4U, 0x0a2c86daU, 0xe9b66dfbU,
216 	0x68dc1462U, 0xd7486900U, 0x680ec0a4U, 0x27a18deeU,
217 	0x4f3ffea2U, 0xe887ad8cU, 0xb58ce006U, 0x7af4d6b6U,
218 	0xaace1e7cU, 0xd3375fecU, 0xce78a399U, 0x406b2a42U,
219 	0x20fe9e35U, 0xd9f385b9U, 0xee39d7abU, 0x3b124e8bU,
220 	0x1dc9faf7U, 0x4b6d1856U, 0x26a36631U, 0xeae397b2U,
221 	0x3a6efa74U, 0xdd5b4332U, 0x6841e7f7U, 0xca7820fbU,
222 	0xfb0af54eU, 0xd8feb397U, 0x454056acU, 0xba489527U,
223 	0x55533a3aU, 0x20838d87U, 0xfe6ba9b7U, 0xd096954bU,
224 	0x55a867bcU, 0xa1159a58U, 0xcca92963U, 0x99e1db33U,
225 	0xa62a4a56U, 0x3f3125f9U, 0x5ef47e1cU, 0x9029317cU,
226 	0xfdf8e802U, 0x04272f70U, 0x80bb155cU, 0x05282ce3U,
227 	0x95c11548U, 0xe4c66d22U, 0x48c1133fU, 0xc70f86dcU,
228 	0x07f9c9eeU, 0x41041f0fU, 0x404779a4U, 0x5d886e17U,
229 	0x325f51ebU, 0xd59bc0d1U, 0xf2bcc18fU, 0x41113564U,
230 	0x257b7834U, 0x602a9c60U, 0xdff8e8a3U, 0x1f636c1bU,
231 	0x0e12b4c2U, 0x02e1329eU, 0xaf664fd1U, 0xcad18115U,
232 	0x6b2395e0U, 0x333e92e1U, 0x3b240b62U, 0xeebeb922U,
233 	0x85b2a20eU, 0xe6ba0d99U, 0xde720c8cU, 0x2da2f728U,
234 	0xd0127845U, 0x95b794fdU, 0x647d0862U, 0xe7ccf5f0U,
235 	0x5449a36fU, 0x877d48faU, 0xc39dfd27U, 0xf33e8d1eU,
236 	0x0a476341U, 0x992eff74U, 0x3a6f6eabU, 0xf4f8fd37U,
237 	0xa812dc60U, 0xa1ebddf8U, 0x991be14cU, 0xdb6e6b0dU,
238 	0xc67b5510U, 0x6d672c37U, 0x2765d43bU, 0xdcd0e804U,
239 	0xf1290dc7U, 0xcc00ffa3U, 0xb5390f92U, 0x690fed0bU,
240 	0x667b9ffbU, 0xcedb7d9cU, 0xa091cf0bU, 0xd9155ea3U,
241 	0xbb132f88U, 0x515bad24U, 0x7b9479bfU, 0x763bd6ebU,
242 	0x37392eb3U, 0xcc115979U, 0x8026e297U, 0xf42e312dU,
243 	0x6842ada7U, 0xc66a2b3bU, 0x12754cccU, 0x782ef11cU,
244 	0x6a124237U, 0xb79251e7U, 0x06a1bbe6U, 0x4bfb6350U,
245 	0x1a6b1018U, 0x11caedfaU, 0x3d25bdd8U, 0xe2e1c3c9U,
246 	0x44421659U, 0x0a121386U, 0xd90cec6eU, 0xd5abea2aU,
247 	0x64af674eU, 0xda86a85fU, 0xbebfe988U, 0x64e4c3feU,
248 	0x9dbc8057U, 0xf0f7c086U, 0x60787bf8U, 0x6003604dU,
249 	0xd1fd8346U, 0xf6381fb0U, 0x7745ae04U, 0xd736fcccU,
250 	0x83426b33U, 0xf01eab71U, 0xb0804187U, 0x3c005e5fU,
251 	0x77a057beU, 0xbde8ae24U, 0x55464299U, 0xbf582e61U,
252 	0x4e58f48fU, 0xf2ddfda2U, 0xf474ef38U, 0x8789bdc2U,
253 	0x5366f9c3U, 0xc8b38e74U, 0xb475f255U, 0x46fcd9b9U,
254 	0x7aeb2661U, 0x8b1ddf84U, 0x846a0e79U, 0x915f95e2U,
255 	0x466e598eU, 0x20b45770U, 0x8cd55591U, 0xc902de4cU,
256 	0xb90bace1U, 0xbb8205d0U, 0x11a86248U, 0x7574a99eU,
257 	0xb77f19b6U, 0xe0a9dc09U, 0x662d09a1U, 0xc4324633U,
258 	0xe85a1f02U, 0x09f0be8cU, 0x4a99a025U, 0x1d6efe10U,
259 	0x1ab93d1dU, 0x0ba5a4dfU, 0xa186f20fU, 0x2868f169U,
260 	0xdcb7da83U, 0x573906feU, 0xa1e2ce9bU, 0x4fcd7f52U,
261 	0x50115e01U, 0xa70683faU, 0xa002b5c4U, 0x0de6d027U,
262 	0x9af88c27U, 0x773f8641U, 0xc3604c06U, 0x61a806b5U,
263 	0xf0177a28U, 0xc0f586e0U, 0x006058aaU, 0x30dc7d62U,
264 	0x11e69ed7U, 0x2338ea63U, 0x53c2dd94U, 0xc2c21634U,
265 	0xbbcbee56U, 0x90bcb6deU, 0xebfc7da1U, 0xce591d76U,
266 	0x6f05e409U, 0x4b7c0188U, 0x39720a3dU, 0x7c927c24U,
267 	0x86e3725fU, 0x724d9db9U, 0x1ac15bb4U, 0xd39eb8fcU,
268 	0xed545578U, 0x08fca5b5U, 0xd83d7cd3U, 0x4dad0fc4U,
269 	0x1e50ef5eU, 0xb161e6f8U, 0xa28514d9U, 0x6c51133cU,
270 	0x6fd5c7e7U, 0x56e14ec4U, 0x362abfceU, 0xddc6c837U,
271 	0xd79a3234U, 0x92638212U, 0x670efa8eU, 0x406000e0U,
272 
273 	/* S-Box 3. */
274 	0x3a39ce37U, 0xd3faf5cfU, 0xabc27737U, 0x5ac52d1bU,
275 	0x5cb0679eU, 0x4fa33742U, 0xd3822740U, 0x99bc9bbeU,
276 	0xd5118e9dU, 0xbf0f7315U, 0xd62d1c7eU, 0xc700c47bU,
277 	0xb78c1b6bU, 0x21a19045U, 0xb26eb1beU, 0x6a366eb4U,
278 	0x5748ab2fU, 0xbc946e79U, 0xc6a376d2U, 0x6549c2c8U,
279 	0x530ff8eeU, 0x468dde7dU, 0xd5730a1dU, 0x4cd04dc6U,
280 	0x2939bbdbU, 0xa9ba4650U, 0xac9526e8U, 0xbe5ee304U,
281 	0xa1fad5f0U, 0x6a2d519aU, 0x63ef8ce2U, 0x9a86ee22U,
282 	0xc089c2b8U, 0x43242ef6U, 0xa51e03aaU, 0x9cf2d0a4U,
283 	0x83c061baU, 0x9be96a4dU, 0x8fe51550U, 0xba645bd6U,
284 	0x2826a2f9U, 0xa73a3ae1U, 0x4ba99586U, 0xef5562e9U,
285 	0xc72fefd3U, 0xf752f7daU, 0x3f046f69U, 0x77fa0a59U,
286 	0x80e4a915U, 0x87b08601U, 0x9b09e6adU, 0x3b3ee593U,
287 	0xe990fd5aU, 0x9e34d797U, 0x2cf0b7d9U, 0x022b8b51U,
288 	0x96d5ac3aU, 0x017da67dU, 0xd1cf3ed6U, 0x7c7d2d28U,
289 	0x1f9f25cfU, 0xadf2b89bU, 0x5ad6b472U, 0x5a88f54cU,
290 	0xe029ac71U, 0xe019a5e6U, 0x47b0acfdU, 0xed93fa9bU,
291 	0xe8d3c48dU, 0x283b57ccU, 0xf8d56629U, 0x79132e28U,
292 	0x785f0191U, 0xed756055U, 0xf7960e44U, 0xe3d35e8cU,
293 	0x15056dd4U, 0x88f46dbaU, 0x03a16125U, 0x0564f0bdU,
294 	0xc3eb9e15U, 0x3c9057a2U, 0x97271aecU, 0xa93a072aU,
295 	0x1b3f6d9bU, 0x1e6321f5U, 0xf59c66fbU, 0x26dcf319U,
296 	0x7533d928U, 0xb155fdf5U, 0x03563482U, 0x8aba3cbbU,
297 	0x28517711U, 0xc20ad9f8U, 0xabcc5167U, 0xccad925fU,
298 	0x4de81751U, 0x3830dc8eU, 0x379d5862U, 0x9320f991U,
299 	0xea7a90c2U, 0xfb3e7bceU, 0x5121ce64U, 0x774fbe32U,
300 	0xa8b6e37eU, 0xc3293d46U, 0x48de5369U, 0x6413e680U,
301 	0xa2ae0810U, 0xdd6db224U, 0x69852dfdU, 0x09072166U,
302 	0xb39a460aU, 0x6445c0ddU, 0x586cdecfU, 0x1c20c8aeU,
303 	0x5bbef7ddU, 0x1b588d40U, 0xccd2017fU, 0x6bb4e3bbU,
304 	0xdda26a7eU, 0x3a59ff45U, 0x3e350a44U, 0xbcb4cdd5U,
305 	0x72eacea8U, 0xfa6484bbU, 0x8d6612aeU, 0xbf3c6f47U,
306 	0xd29be463U, 0x542f5d9eU, 0xaec2771bU, 0xf64e6370U,
307 	0x740e0d8dU, 0xe75b1357U, 0xf8721671U, 0xaf537d5dU,
308 	0x4040cb08U, 0x4eb4e2ccU, 0x34d2466aU, 0x0115af84U,
309 	0xe1b00428U, 0x95983a1dU, 0x06b89fb4U, 0xce6ea048U,
310 	0x6f3f3b82U, 0x3520ab82U, 0x011a1d4bU, 0x277227f8U,
311 	0x611560b1U, 0xe7933fdcU, 0xbb3a792bU, 0x344525bdU,
312 	0xa08839e1U, 0x51ce794bU, 0x2f32c9b7U, 0xa01fbac9U,
313 	0xe01cc87eU, 0xbcc7d1f6U, 0xcf0111c3U, 0xa1e8aac7U,
314 	0x1a908749U, 0xd44fbd9aU, 0xd0dadecbU, 0xd50ada38U,
315 	0x0339c32aU, 0xc6913667U, 0x8df9317cU, 0xe0b12b4fU,
316 	0xf79e59b7U, 0x43f5bb3aU, 0xf2d519ffU, 0x27d9459cU,
317 	0xbf97222cU, 0x15e6fc2aU, 0x0f91fc71U, 0x9b941525U,
318 	0xfae59361U, 0xceb69cebU, 0xc2a86459U, 0x12baa8d1U,
319 	0xb6c1075eU, 0xe3056a0cU, 0x10d25065U, 0xcb03a442U,
320 	0xe0ec6e0eU, 0x1698db3bU, 0x4c98a0beU, 0x3278e964U,
321 	0x9f1f9532U, 0xe0d392dfU, 0xd3a0342bU, 0x8971f21eU,
322 	0x1b0a7441U, 0x4ba3348cU, 0xc5be7120U, 0xc37632d8U,
323 	0xdf359f8dU, 0x9b992f2eU, 0xe60b6f47U, 0x0fe3f11dU,
324 	0xe54cda54U, 0x1edad891U, 0xce6279cfU, 0xcd3e7e6fU,
325 	0x1618b166U, 0xfd2c1d05U, 0x848fd2c5U, 0xf6fb2299U,
326 	0xf523f357U, 0xa6327623U, 0x93a83531U, 0x56cccd02U,
327 	0xacf08162U, 0x5a75ebb5U, 0x6e163697U, 0x88d273ccU,
328 	0xde966292U, 0x81b949d0U, 0x4c50901bU, 0x71c65614U,
329 	0xe6c6c7bdU, 0x327a140aU, 0x45e1d006U, 0xc3f27b9aU,
330 	0xc9aa53fdU, 0x62a80f00U, 0xbb25bfe2U, 0x35bdd2f6U,
331 	0x71126905U, 0xb2040222U, 0xb6cbcf7cU, 0xcd769c2bU,
332 	0x53113ec0U, 0x1640e3d3U, 0x38abbd60U, 0x2547adf0U,
333 	0xba38209cU, 0xf746ce76U, 0x77afa1c5U, 0x20756060U,
334 	0x85cbfe4eU, 0x8ae88dd8U, 0x7aaaf9b0U, 0x4cf9aa7eU,
335 	0x1948c25cU, 0x02fb8a8cU, 0x01c36ae4U, 0xd6ebe1f9U,
336 	0x90d4f869U, 0xa65cdea0U, 0x3f09252dU, 0xc208e69fU,
337 	0xb74e6132U, 0xce77e25bU, 0x578fdfe3U, 0x3ac372e6U,
338 };
339 
340 typedef struct keysched_s {
341 	uint32_t ksch_S[1024];	/* The 4 S boxes are 256 32-bit words. */
342 	uint32_t ksch_P[18];	/* P box is 18 32-bit words. */
343 } keysched_t;
344 
345 /*
346  * Since ROUND() is a macro, make sure that the things inside can be
347  * evaluated more than once.  Especially when calling F().
348  * Assume the presence of local variables:
349  *
350  *	uint32_t *P;
351  *	uint32_t *S;
352  *	uint32_t tmp;
353  *
354  *
355  * And to Microsoft interview survivors out there, perhaps I should do the
356  * XOR swap trick, or at least #ifdef (__i386) the tmp = ... = tmp; stuff.
357  */
358 
359 #define	F(word) \
360 	(((S[(word >> 24) & 0xff] + S[256 + ((word >> 16) & 0xff)]) ^ \
361 		S[512 + ((word >> 8) & 0xff)]) + S[768 + (word & 0xff)])
362 
363 #define	ROUND(left, right, i) \
364 	(left) ^= P[i]; \
365 	(right) ^= F((left)); \
366 	tmp = (left); \
367 	(left) = (right); \
368 	(right) = tmp;
369 
370 /* EXPORT DELETE END */
371 
372 /*
373  * Encrypt a block of data.  Because of addition operations, convert blocks
374  * to their big-endian representation, even on Intel boxen.
375  */
376 /* ARGSUSED */
377 int
378 blowfish_encrypt_block(const void *cookie, const uint8_t *block,
379     uint8_t *out_block)
380 {
381 /* EXPORT DELETE START */
382 	keysched_t *ksch = (keysched_t *)cookie;
383 
384 	uint32_t left, right, tmp;
385 	uint32_t *P = ksch->ksch_P;
386 	uint32_t *S = ksch->ksch_S;
387 #ifdef _BIG_ENDIAN
388 	uint32_t *b32;
389 
390 	if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
391 		/* LINTED:  pointer alignment */
392 		b32 = (uint32_t *)block;
393 		left = b32[0];
394 		right = b32[1];
395 	} else
396 #endif
397 	{
398 	/*
399 	 * Read input block and place in left/right in big-endian order.
400 	 */
401 #ifdef UNALIGNED_POINTERS_PERMITTED
402 	left = htonl(*(uint32_t *)(void *)&block[0]);
403 	right = htonl(*(uint32_t *)(void *)&block[4]);
404 #else
405 	left = ((uint32_t)block[0] << 24)
406 	    | ((uint32_t)block[1] << 16)
407 	    | ((uint32_t)block[2] << 8)
408 	    | (uint32_t)block[3];
409 	right = ((uint32_t)block[4] << 24)
410 	    | ((uint32_t)block[5] << 16)
411 	    | ((uint32_t)block[6] << 8)
412 	    | (uint32_t)block[7];
413 #endif	/* UNALIGNED_POINTERS_PERMITTED */
414 	}
415 
416 	ROUND(left, right, 0);
417 	ROUND(left, right, 1);
418 	ROUND(left, right, 2);
419 	ROUND(left, right, 3);
420 	ROUND(left, right, 4);
421 	ROUND(left, right, 5);
422 	ROUND(left, right, 6);
423 	ROUND(left, right, 7);
424 	ROUND(left, right, 8);
425 	ROUND(left, right, 9);
426 	ROUND(left, right, 10);
427 	ROUND(left, right, 11);
428 	ROUND(left, right, 12);
429 	ROUND(left, right, 13);
430 	ROUND(left, right, 14);
431 	ROUND(left, right, 15);
432 
433 	tmp = left;
434 	left = right;
435 	right = tmp;
436 	right ^= P[16];
437 	left ^= P[17];
438 
439 #ifdef _BIG_ENDIAN
440 	if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
441 		/* LINTED:  pointer alignment */
442 		b32 = (uint32_t *)out_block;
443 		b32[0] = left;
444 		b32[1] = right;
445 	} else
446 #endif
447 	{
448 		/* Put the block back into the user's block with final swap */
449 #ifdef UNALIGNED_POINTERS_PERMITTED
450 		*(uint32_t *)(void *)&out_block[0] = htonl(left);
451 		*(uint32_t *)(void *)&out_block[4] = htonl(right);
452 #else
453 		out_block[0] = left >> 24;
454 		out_block[1] = left >> 16;
455 		out_block[2] = left >> 8;
456 		out_block[3] = left;
457 		out_block[4] = right >> 24;
458 		out_block[5] = right >> 16;
459 		out_block[6] = right >> 8;
460 		out_block[7] = right;
461 #endif	/* UNALIGNED_POINTERS_PERMITTED */
462 	}
463 /* EXPORT DELETE END */
464 	return (CRYPTO_SUCCESS);
465 }
466 
467 /*
468  * Decrypt a block of data.  Because of addition operations, convert blocks
469  * to their big-endian representation, even on Intel boxen.
470  * It should look like the blowfish_encrypt_block() operation
471  * except for the order in which the S/P boxes are accessed.
472  */
473 /* ARGSUSED */
474 int
475 blowfish_decrypt_block(const void *cookie, const uint8_t *block,
476     uint8_t *out_block)
477 {
478 /* EXPORT DELETE START */
479 	keysched_t *ksch = (keysched_t *)cookie;
480 
481 	uint32_t left, right, tmp;
482 	uint32_t *P = ksch->ksch_P;
483 	uint32_t *S = ksch->ksch_S;
484 #ifdef _BIG_ENDIAN
485 	uint32_t *b32;
486 
487 	if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
488 		/* LINTED:  pointer alignment */
489 		b32 = (uint32_t *)block;
490 		left = b32[0];
491 		right = b32[1];
492 	} else
493 #endif
494 	{
495 	/*
496 	 * Read input block and place in left/right in big-endian order.
497 	 */
498 #ifdef UNALIGNED_POINTERS_PERMITTED
499 	left = htonl(*(uint32_t *)(void *)&block[0]);
500 	right = htonl(*(uint32_t *)(void *)&block[4]);
501 #else
502 	left = ((uint32_t)block[0] << 24)
503 	    | ((uint32_t)block[1] << 16)
504 	    | ((uint32_t)block[2] << 8)
505 	    | (uint32_t)block[3];
506 	right = ((uint32_t)block[4] << 24)
507 	    | ((uint32_t)block[5] << 16)
508 	    | ((uint32_t)block[6] << 8)
509 	    | (uint32_t)block[7];
510 #endif	/* UNALIGNED_POINTERS_PERMITTED */
511 	}
512 
513 	ROUND(left, right, 17);
514 	ROUND(left, right, 16);
515 	ROUND(left, right, 15);
516 	ROUND(left, right, 14);
517 	ROUND(left, right, 13);
518 	ROUND(left, right, 12);
519 	ROUND(left, right, 11);
520 	ROUND(left, right, 10);
521 	ROUND(left, right, 9);
522 	ROUND(left, right, 8);
523 	ROUND(left, right, 7);
524 	ROUND(left, right, 6);
525 	ROUND(left, right, 5);
526 	ROUND(left, right, 4);
527 	ROUND(left, right, 3);
528 	ROUND(left, right, 2);
529 
530 	tmp = left;
531 	left = right;
532 	right = tmp;
533 	right ^= P[1];
534 	left ^= P[0];
535 
536 #ifdef _BIG_ENDIAN
537 	if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
538 		/* LINTED:  pointer alignment */
539 		b32 = (uint32_t *)out_block;
540 		b32[0] = left;
541 		b32[1] = right;
542 	} else
543 #endif
544 	{
545 	/* Put the block back into the user's block with final swap */
546 #ifdef UNALIGNED_POINTERS_PERMITTED
547 		*(uint32_t *)(void *)&out_block[0] = htonl(left);
548 		*(uint32_t *)(void *)&out_block[4] = htonl(right);
549 #else
550 		out_block[0] = left >> 24;
551 		out_block[1] = left >> 16;
552 		out_block[2] = left >> 8;
553 		out_block[3] = left;
554 		out_block[4] = right >> 24;
555 		out_block[5] = right >> 16;
556 		out_block[6] = right >> 8;
557 		out_block[7] = right;
558 #endif	/* UNALIGNED_POINTERS_PERMITTED */
559 	}
560 /* EXPORT DELETE END */
561 	return (CRYPTO_SUCCESS);
562 }
563 
564 static void
565 bitrepeat(uint8_t *pattern, uint_t len_bytes, uint_t len_bits, uint8_t *dst,
566     uint_t dst_len_bytes)
567 {
568 /* EXPORT DELETE START */
569 	uint8_t *current = dst;
570 	uint_t bitsleft = CRYPTO_BYTES2BITS(dst_len_bytes);
571 	uint_t bitoffset = 0;
572 	uint_t currentbits;
573 	int i;
574 
575 	BLOWFISH_ASSERT(CRYPTO_BITS2BYTES(len_bits) == len_bytes);
576 
577 	bzero(dst, dst_len_bytes);
578 
579 	while (bitsleft != 0) {
580 		if (bitsleft >= len_bits) {
581 			currentbits = len_bits;
582 
583 			for (i = 0; i < len_bytes; i++) {
584 				if (currentbits >= 8) {
585 					*current++ |= pattern[i] >> bitoffset;
586 					*current |= pattern[i] << 8 - bitoffset;
587 					currentbits -= 8;
588 				} else {
589 					*current |= pattern[i] >> bitoffset;
590 					bitoffset = bitoffset + currentbits;
591 					bitoffset &= 0x7;
592 					if (bitoffset == 0)
593 						current++;
594 				}
595 			}
596 			bitsleft -= len_bits;
597 		} else {
598 			currentbits = bitsleft;
599 
600 			for (i = 0; i < len_bytes && bitsleft != 0; i++) {
601 				if (currentbits >= 8 &&
602 				    current < dst + dst_len_bytes) {
603 					*current++ |= pattern[i] >> bitoffset;
604 					*current |= pattern[i] << 8 - bitoffset;
605 					currentbits -= 8;
606 					bitsleft -= 8;
607 				} else {
608 					*current |= pattern[i] >> bitoffset;
609 					bitsleft -= bitoffset;
610 					bitoffset = bitoffset + currentbits;
611 					bitoffset &= 0x7;
612 					if (bitoffset == 0)
613 						current++;
614 					currentbits = 0;
615 				}
616 			}
617 			bitsleft = 0;
618 		}
619 	}
620 /* EXPORT DELETE END */
621 }
622 
623 /*
624  * Initialize key schedules for Blowfish.
625  */
626 void
627 blowfish_init_keysched(uint8_t *key, uint_t bits, void *keysched)
628 {
629 /* EXPORT DELETE START */
630 	keysched_t *newbie = keysched;
631 	uint32_t *P = newbie->ksch_P;
632 	uint32_t *S = newbie->ksch_S;
633 	uint32_t *initp;
634 	uint32_t tmpblock[] = {0, 0};
635 	uint8_t *rawkeybytes = (uint8_t *)P;
636 	int i, slop, copylen;
637 	uintptr_t bytesleft;
638 	uint_t len;
639 
640 	len = CRYPTO_BITS2BYTES(bits);
641 
642 	if ((bits & 0x7) != 0) {
643 		/*
644 		 * Really slow case, bits aren't on a byte boundary.
645 		 * Keep track of individual bits copied over.  :-P
646 		 */
647 		bitrepeat(key, len, bits, rawkeybytes, 72);
648 	} else {
649 		slop = 72 % len;
650 
651 		/* Someone gave us a nice amount (i.e. div by 8) of bits */
652 		while (rawkeybytes != (uint8_t *)(P + 18)) {
653 			bytesleft =
654 			    (uintptr_t)(P + 18) - (uintptr_t)rawkeybytes;
655 			copylen = (bytesleft >= len) ? len : slop;
656 			bcopy(key, rawkeybytes, copylen);
657 			rawkeybytes += copylen;
658 		}
659 	}
660 
661 	for (i = 0; i < 18; i++)
662 		P[i] = ntohl(P[i]) ^ init_P[i];
663 
664 	/* Go bcopy go!  (Hope that Ultra's bcopy is faster than me!) */
665 	bcopy(init_S, S, sizeof (init_S));
666 
667 	/*
668 	 * When initializing P and S boxes, store the results of a single
669 	 * encrypt-block operation in "host order", which on little-endian
670 	 * means byte-swapping.  Fortunately, the ntohl() function does this
671 	 * quite nicely, and it a NOP on big-endian machine.
672 	 */
673 	initp = P;
674 	for (i = 0; i < 9; i++) {
675 		(void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
676 		    (uint8_t *)tmpblock);
677 		*initp++ = ntohl(tmpblock[0]);
678 		*initp++ = ntohl(tmpblock[1]);
679 	}
680 
681 	initp = S;
682 	for (i = 0; i < 512; i++) {
683 		(void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
684 		    (uint8_t *)tmpblock);
685 		*initp++ = ntohl(tmpblock[0]);
686 		*initp++ = ntohl(tmpblock[1]);
687 	}
688 /* EXPORT DELETE END */
689 }
690 
691 /*
692  * Allocate key schedule for Blowfish.
693  */
694 /* ARGSUSED */
695 void *
696 blowfish_alloc_keysched(size_t *size, int kmflag)
697 {
698 /* EXPORT DELETE START */
699 	keysched_t *keysched;
700 
701 #ifdef _KERNEL
702 	keysched = (keysched_t *)kmem_alloc(sizeof (keysched_t), kmflag);
703 #else
704 	keysched = (keysched_t *)malloc(sizeof (keysched_t));
705 #endif /* _KERNEL */
706 	if (keysched != NULL) {
707 		*size = sizeof (keysched_t);
708 		return (keysched);
709 	}
710 /* EXPORT DELETE END */
711 
712 	return (NULL);
713 }
714 
715 void
716 blowfish_copy_block(uint8_t *in, uint8_t *out)
717 {
718 	if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
719 	    IS_P2ALIGNED(out, sizeof (uint32_t))) {
720 		/* LINTED: pointer alignment */
721 		*(uint32_t *)&out[0] = *(uint32_t *)&in[0];
722 		/* LINTED: pointer alignment */
723 		*(uint32_t *)&out[4] = *(uint32_t *)&in[4];
724 	} else {
725 		BLOWFISH_COPY_BLOCK(in, out);
726 	}
727 }
728 
729 /* XOR block of data into dest */
730 void
731 blowfish_xor_block(uint8_t *data, uint8_t *dst)
732 {
733 	if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
734 	    IS_P2ALIGNED(data, sizeof (uint32_t))) {
735 		/* LINTED: pointer alignment */
736 		*(uint32_t *)&dst[0] ^= *(uint32_t *)&data[0];
737 		/* LINTED: pointer alignment */
738 		*(uint32_t *)&dst[4] ^= *(uint32_t *)&data[4];
739 	} else {
740 		BLOWFISH_XOR_BLOCK(data, dst);
741 	}
742 }
743 
744 /*
745  * Encrypt multiple blocks of data according to mode.
746  */
747 int
748 blowfish_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
749     crypto_data_t *out)
750 {
751 	blowfish_ctx_t *blowfish_ctx = ctx;
752 	int rv;
753 
754 	if (blowfish_ctx->bc_flags & CBC_MODE) {
755 		rv = cbc_encrypt_contiguous_blocks(ctx, data, length, out,
756 		    BLOWFISH_BLOCK_LEN, blowfish_encrypt_block,
757 		    blowfish_copy_block, blowfish_xor_block);
758 	} else {
759 		rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
760 		    BLOWFISH_BLOCK_LEN, blowfish_encrypt_block);
761 	}
762 	return (rv);
763 }
764 
765 /*
766  * Decrypt multiple blocks of data according to mode.
767  */
768 int
769 blowfish_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
770     crypto_data_t *out)
771 {
772 	blowfish_ctx_t *blowfish_ctx = ctx;
773 	int rv;
774 
775 	if (blowfish_ctx->bc_flags & CBC_MODE) {
776 		rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out,
777 		    BLOWFISH_BLOCK_LEN, blowfish_decrypt_block,
778 		    blowfish_copy_block, blowfish_xor_block);
779 	} else {
780 		rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
781 		    BLOWFISH_BLOCK_LEN, blowfish_decrypt_block);
782 		if (rv == CRYPTO_DATA_LEN_RANGE)
783 			rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
784 	}
785 	return (rv);
786 }
787