Print this page
6652716 Need an ARCFOUR implementation optimized for Intel EM64T
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
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
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 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "@(#)arcfour_crypt.c 1.6 08/01/02 SMI"
26 +#pragma ident "@(#)arcfour_crypt.c 1.7 08/03/20 SMI"
27 27
28 28 #include "arcfour.h"
29 29
30 30 #if defined(__amd64)
31 -/*
32 - * Use hand-tuned, processor-specific assembly version of arcfour_crypt()
33 - * for 64-bit x86:
34 - */
35 -#define USE_PSR_VERSION_OF_ARCFOUR_CRYPT
36 -#endif /* __amd64 */
31 +#ifdef _KERNEL
32 +#include <sys/x86_archext.h>
33 +#include <sys/cpuvar.h>
37 34
35 +#else
36 +#include <sys/auxv.h>
37 +#endif /* _KERNEL */
38 +#endif /* __amd64 */
39 +
40 +#if !defined(__amd64)
38 41 /* Initialize the key stream 'key' using the key value */
39 42 void
40 43 arcfour_key_init(ARCFour_key *key, uchar_t *keyval, int keyvallen)
41 44 {
42 45 /* EXPORT DELETE START */
43 46
44 47 uchar_t ext_keyval[256];
45 48 uchar_t tmp;
46 49 int i, j;
47 50
51 + /* Normalize key length to 256 */
48 52 for (i = j = 0; i < 256; i++, j++) {
49 53 if (j == keyvallen)
50 54 j = 0;
51 -
52 55 ext_keyval[i] = keyval[j];
53 56 }
57 +
54 58 for (i = 0; i < 256; i++)
55 59 key->arr[i] = (uchar_t)i;
56 60
57 61 j = 0;
58 62 for (i = 0; i < 256; i++) {
59 63 j = (j + key->arr[i] + ext_keyval[i]) % 256;
60 64 tmp = key->arr[i];
61 65 key->arr[i] = key->arr[j];
62 66 key->arr[j] = tmp;
63 67 }
64 68 key->i = 0;
65 69 key->j = 0;
66 70
67 71 /* EXPORT DELETE END */
68 72 }
69 73
70 74
71 -#if !defined(USE_PSR_VERSION_OF_ARCFOUR_CRYPT)
72 75 /*
73 76 * Encipher 'in' using 'key'.
74 77 * in and out can point to the same location
75 78 */
76 79 void
77 80 arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
78 81 {
79 82 size_t ii;
80 83 uchar_t tmp, i, j;
81 84
82 85 /* EXPORT DELETE START */
83 86
84 87 /*
85 88 * The sun4u has a version of arcfour_crypt_aligned() hand-tuned for
86 89 * the cases where the input and output buffers are aligned on
87 90 * a multiple of 8-byte boundary.
88 91 */
89 92 #ifdef sun4u
90 93 int index;
91 94
92 95 index = (((uint64_t)(uintptr_t)in) & 0x7);
93 96
94 97 /* Get the 'in' on an 8-byte alignment */
95 98 if (index > 0) {
96 99 i = key->i;
97 100 j = key->j;
98 101 for (index = 8 - (uint64_t)(uintptr_t)in & 0x7;
99 102 (index-- > 0) && len > 0;
100 103 len--, in++, out++) {
101 104 i = i + 1;
102 105 j = j + key->arr[i];
103 106 tmp = key->arr[i];
104 107 key->arr[i] = key->arr[j];
105 108 key->arr[j] = tmp;
106 109 tmp = key->arr[i] + key->arr[j];
107 110 *out = *in ^ key->arr[tmp];
108 111 }
109 112 key->i = i;
110 113 key->j = j;
111 114
112 115 }
113 116 if (len == 0)
114 117 return;
115 118
116 119 /* See if we're fortunate and 'out' got aligned as well */
117 120
118 121 if ((((uint64_t)(uintptr_t)out) & 7) != 0) {
119 122 #endif /* sun4u */
120 123 i = key->i;
121 124 j = key->j;
122 125 for (ii = 0; ii < len; ii++) {
123 126 i = i + 1;
124 127 j = j + key->arr[i];
125 128 tmp = key->arr[i];
126 129 key->arr[i] = key->arr[j];
127 130 key->arr[j] = tmp;
128 131 tmp = key->arr[i] + key->arr[j];
129 132 out[ii] = in[ii] ^ key->arr[tmp];
130 133 }
↓ open down ↓ |
49 lines elided |
↑ open up ↑ |
131 134 key->i = i;
132 135 key->j = j;
133 136 #ifdef sun4u
134 137 } else {
135 138 arcfour_crypt_aligned(key, len, in, out);
136 139 }
137 140 #endif /* sun4u */
138 141
139 142 /* EXPORT DELETE END */
140 143 }
141 -#endif /* !USE_PSR_VERSION_OF_ARCFOUR_CRYPT */
144 +
145 +#else
146 +
147 +/*
148 + * Return 1 if executing on Intel, otherwise 0 (e.g., AMD64).
149 + */
150 +int
151 +arcfour_crypt_on_intel(void)
152 +{
153 +#ifdef _KERNEL
154 + return (cpuid_getvendor(CPU) == X86_VENDOR_Intel);
155 +#else
156 + uint_t ui;
157 + (void) getisax(&ui, 1);
158 + return ((ui & AV_386_AMD_MMX) == 0);
159 +#endif /* _KERNEL */
160 +}
161 +#endif /* !__amd64 */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX