Print this page
first pass
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/common/crypto/arcfour/arcfour_crypt.c
+++ new/usr/src/common/crypto/arcfour/arcfour_crypt.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #define ARCFOUR_LOOP_OPTIMIZED
27 27
28 28 #ifndef _KERNEL
29 29 #include <stdint.h>
30 30 #endif /* _KERNEL */
31 31
32 32 #include "arcfour.h"
33 33
34 34 #if defined(__amd64)
35 35 /* ARCFour_key.flag values */
36 36 #define ARCFOUR_ON_INTEL 1
37 37 #define ARCFOUR_ON_AMD64 0
38 38
39 39 #ifdef _KERNEL
40 40 #include <sys/x86_archext.h>
41 41 #include <sys/cpuvar.h>
42 42
43 43 #else
44 44 #include <sys/auxv.h>
45 45 #endif /* _KERNEL */
46 46 #endif /* __amd64 */
47 47
48 48 #ifndef __amd64
49 49 /*
50 50 * Initialize the key stream 'key' using the key value.
↓ open down ↓ |
50 lines elided |
↑ open up ↑ |
51 51 *
52 52 * Input:
53 53 * keyval User-provided key
54 54 * keyvallen Length, in bytes, of keyval
55 55 * Output:
56 56 * key Initialized ARCFOUR key schedule, based on keyval
57 57 */
58 58 void
59 59 arcfour_key_init(ARCFour_key *key, uchar_t *keyval, int keyvallen)
60 60 {
61 -/* EXPORT DELETE START */
62 -
63 61 uchar_t ext_keyval[256];
64 62 uchar_t tmp;
65 63 int i, j;
66 64
67 65 /* Normalize key length to 256 */
68 66 for (i = j = 0; i < 256; i++, j++) {
69 67 if (j == keyvallen)
70 68 j = 0;
71 69 ext_keyval[i] = keyval[j];
72 70 }
73 71
74 72 for (i = 0; i < 256; i++)
75 73 key->arr[i] = (uchar_t)i;
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
76 74
77 75 j = 0;
78 76 for (i = 0; i < 256; i++) {
79 77 j = (j + key->arr[i] + ext_keyval[i]) & 0xff;
80 78 tmp = key->arr[i];
81 79 key->arr[i] = key->arr[j];
82 80 key->arr[j] = tmp;
83 81 }
84 82 key->i = 0;
85 83 key->j = 0;
86 -
87 -/* EXPORT DELETE END */
88 84 }
89 85 #endif /* !__amd64 */
90 86
91 87
92 88 /*
93 89 * Encipher 'in' using 'key'.
94 90 *
95 91 * Input:
96 92 * key ARCFOUR key, initialized by arcfour_key_init()
97 93 * in Input text
98 94 * out Buffer to contain output text
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
99 95 * len Length, in bytes, of the in and out buffers
100 96 *
101 97 * Output:
102 98 * out Buffer containing output text
103 99 *
104 100 * Note: in and out can point to the same location
105 101 */
106 102 void
107 103 arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
108 104 {
109 -/* EXPORT DELETE START */
110 105 #ifdef __amd64
111 106 if (key->flag == ARCFOUR_ON_AMD64) {
112 107 arcfour_crypt_asm(key, in, out, len);
113 108 } else { /* Intel EM64T */
114 109 #endif /* amd64 */
115 110
116 111 size_t ii;
117 112 uchar_t i, j, ti, tj;
118 113 #ifdef ARCFOUR_LOOP_OPTIMIZED
119 114 uchar_t arr_ij;
120 115 #endif
121 116 #ifdef __amd64
122 117 uint32_t *arr;
123 118 #else
124 119 uchar_t *arr;
125 120 #endif
126 121
127 122 #ifdef sun4u
128 123 /*
129 124 * The sun4u has a version of arcfour_crypt_aligned() hand-tuned for
130 125 * the cases where the input and output buffers are aligned on
131 126 * a multiple of 8-byte boundary.
132 127 */
133 128 int index;
134 129 uchar_t tmp;
135 130
136 131 index = (((uint64_t)(uintptr_t)in) & 0x7);
137 132
138 133 /* Get the 'in' on an 8-byte alignment */
139 134 if (index > 0) {
140 135 i = key->i;
141 136 j = key->j;
142 137 for (index = 8 - (uint64_t)(uintptr_t)in & 0x7;
143 138 (index-- > 0) && len > 0;
144 139 len--, in++, out++) {
145 140 ++i;
146 141 j = j + key->arr[i];
147 142 tmp = key->arr[i];
148 143 key->arr[i] = key->arr[j];
149 144 key->arr[j] = tmp;
150 145 tmp = key->arr[i] + key->arr[j];
151 146 *out = *in ^ key->arr[tmp];
152 147 }
153 148 key->i = i;
154 149 key->j = j;
155 150 }
156 151
157 152 if (len == 0)
158 153 return;
159 154
160 155 /* See if we're fortunate and 'out' got aligned as well */
161 156
162 157 if ((((uint64_t)(uintptr_t)out) & 7) != 0) {
163 158 #endif /* sun4u */
164 159
165 160 i = key->i;
166 161 j = key->j;
167 162 arr = key->arr;
168 163
169 164 #ifndef ARCFOUR_LOOP_OPTIMIZED
170 165 /*
171 166 * This loop is hasn't been reordered, but is kept for reference
172 167 * purposes as it's more readable
173 168 */
174 169 for (ii = 0; ii < len; ++ii) {
175 170 ++i;
176 171 ti = arr[i];
177 172 j = j + ti;
178 173 tj = arr[j];
179 174 arr[j] = ti;
180 175 arr[i] = tj;
181 176 out[ii] = in[ii] ^ arr[(ti + tj) & 0xff];
182 177 }
183 178
184 179 #else
185 180 /*
186 181 * This for loop is optimized by carefully spreading out
187 182 * memory access and storage to avoid conflicts,
188 183 * allowing the processor to process operations in parallel
189 184 */
190 185
191 186 /* for loop setup */
192 187 ++i;
193 188 ti = arr[i];
194 189 j = j + ti;
195 190 tj = arr[j];
196 191 arr[j] = ti;
197 192 arr[i] = tj;
198 193 arr_ij = arr[(ti + tj) & 0xff];
199 194 --len;
200 195
201 196 for (ii = 0; ii < len; ) {
202 197 ++i;
203 198 ti = arr[i];
204 199 j = j + ti;
205 200 tj = arr[j];
206 201 arr[j] = ti;
207 202 arr[i] = tj;
208 203
209 204 /* save result from previous loop: */
210 205 out[ii] = in[ii] ^ arr_ij;
211 206
212 207 ++ii;
213 208 arr_ij = arr[(ti + tj) & 0xff];
214 209 }
215 210 /* save result from last loop: */
216 211 out[ii] = in[ii] ^ arr_ij;
217 212 #endif
218 213
219 214 key->i = i;
↓ open down ↓ |
100 lines elided |
↑ open up ↑ |
220 215 key->j = j;
221 216
222 217 #ifdef sun4u
223 218 } else {
224 219 arcfour_crypt_aligned(key, len, in, out);
225 220 }
226 221 #endif /* sun4u */
227 222 #ifdef __amd64
228 223 }
229 224 #endif /* amd64 */
230 -
231 -/* EXPORT DELETE END */
232 225 }
233 226
234 227
235 228 #ifdef __amd64
236 229 /*
237 230 * Return 1 if executing on Intel, otherwise 0 (e.g., AMD64).
238 231 * Cache the result, as the CPU can't change.
239 232 *
240 233 * Note: the userland version uses getisax() and checks for an AMD-64-only
241 234 * feature. The kernel version uses cpuid_getvendor().
242 235 */
243 236 int
244 237 arcfour_crypt_on_intel(void)
245 238 {
246 239 static int cached_result = -1;
247 240
248 241 if (cached_result == -1) { /* first time */
249 242 #ifdef _KERNEL
250 243 cached_result = (cpuid_getvendor(CPU) == X86_VENDOR_Intel);
251 244 #else
252 245 uint_t ui;
253 246
254 247 (void) getisax(&ui, 1);
255 248 cached_result = ((ui & AV_386_AMD_MMX) == 0);
256 249 #endif /* _KERNEL */
257 250 }
258 251
259 252 return (cached_result);
260 253 }
261 254 #endif /* __amd64 */
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX