1 /* |
|
2 * This product includes cryptographic software developed by the OpenSSL |
|
3 * Project for use in the OpenSSL Toolkit (http://www.openssl.org/). |
|
4 */ |
|
5 |
|
6 /* |
|
7 * ==================================================================== |
|
8 * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. |
|
9 * |
|
10 * Redistribution and use in source and binary forms, with or without |
|
11 * modification, are permitted provided that the following conditions |
|
12 * are met: |
|
13 * |
|
14 * 1. Redistributions of source code must retain the above copyright |
|
15 * notice, this list of conditions and the following disclaimer. |
|
16 * |
|
17 * 2. Redistributions in binary form must reproduce the above copyright |
|
18 * notice, this list of conditions and the following disclaimer in |
|
19 * the documentation and/or other materials provided with the |
|
20 * distribution. |
|
21 * |
|
22 * 3. All advertising materials mentioning features or use of this |
|
23 * software must display the following acknowledgment: |
|
24 * "This product includes software developed by the OpenSSL Project |
|
25 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
|
26 * |
|
27 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
|
28 * endorse or promote products derived from this software without |
|
29 * prior written permission. For written permission, please contact |
|
30 * [email protected]. |
|
31 * |
|
32 * 5. Products derived from this software may not be called "OpenSSL" |
|
33 * nor may "OpenSSL" appear in their names without prior written |
|
34 * permission of the OpenSSL Project. |
|
35 * |
|
36 * 6. Redistributions of any form whatsoever must retain the following |
|
37 * acknowledgment: |
|
38 * "This product includes software developed by the OpenSSL Project |
|
39 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
|
40 * |
|
41 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
|
42 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
|
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
48 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
|
52 * OF THE POSSIBILITY OF SUCH DAMAGE. |
|
53 * ==================================================================== |
|
54 */ |
|
55 |
|
56 /* |
|
57 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
|
58 */ |
|
59 |
|
60 /* |
|
61 * This engine supports SPARC microprocessors that provide DES and other |
|
62 * cipher and hash instructions, such as the T4 microprocessor. |
|
63 */ |
|
64 |
|
65 #include <openssl/opensslconf.h> |
|
66 |
|
67 #if !defined(OPENSSL_NO_HW) |
|
68 #include <sys/types.h> |
|
69 #include <sys/auxv.h> /* getisax() */ |
|
70 #include <stdlib.h> |
|
71 #include <stdbool.h> |
|
72 #include <string.h> |
|
73 #include <errno.h> |
|
74 #include <openssl/engine.h> |
|
75 |
|
76 #define T4_LIB_NAME "SPARC T4 engine" |
|
77 #include "eng_t4_err.c" |
|
78 |
|
79 /* Constants used when creating the ENGINE */ |
|
80 static const char *ENGINE_T4_ID = "t4"; |
|
81 static const char *ENGINE_T4_NAME = "SPARC T4 engine support"; |
|
82 static const char *ENGINE_NO_T4_NAME = "SPARC T4 engine support (no T4)"; |
|
83 |
|
84 |
|
85 #if (defined(sun4v) || defined(__sparcv9) || defined(__sparcv8plus) || \ |
|
86 defined(__sparcv8)) && !defined(OPENSSL_NO_ASM) |
|
87 #define COMPILE_HW_T4 |
|
88 static int t4_bind_helper(ENGINE *e, const char *id); |
|
89 #pragma inline(t4_bind_helper) |
|
90 #endif |
|
91 |
|
92 /* |
|
93 * This makes the engine "built-in" with OpenSSL. |
|
94 * On non-T4 CPUs this just returns. |
|
95 * Called by ENGINE_load_builtin_engines(). |
|
96 */ |
|
97 void |
|
98 ENGINE_load_t4(void) |
|
99 { |
|
100 #ifdef COMPILE_HW_T4 |
|
101 ENGINE *toadd = ENGINE_new(); |
|
102 if (toadd != NULL) { |
|
103 if (t4_bind_helper(toadd, ENGINE_T4_ID) != 0) { |
|
104 (void) ENGINE_add(toadd); |
|
105 (void) ENGINE_free(toadd); |
|
106 ERR_clear_error(); |
|
107 } else { |
|
108 (void) ENGINE_free(toadd); |
|
109 } |
|
110 } |
|
111 #endif |
|
112 } |
|
113 |
|
114 |
|
115 #ifdef COMPILE_HW_T4 |
|
116 static int t4_bind(ENGINE *e); |
|
117 #ifndef DYNAMIC_ENGINE |
|
118 #pragma inline(t4_bind) |
|
119 #endif |
|
120 static void t4_instructions_present(_Bool *des_present, _Bool *montmul_present); |
|
121 #pragma inline(t4_instructions_present) |
|
122 |
|
123 /* RSA_METHOD structure used by ENGINE_set_RSA() */ |
|
124 extern RSA_METHOD *t4_RSA(void); |
|
125 |
|
126 /* DH_METHOD structure used by ENGINE_set_DH() */ |
|
127 extern DH_METHOD *t4_DH(void); |
|
128 |
|
129 /* DSA_METHOD structure used by ENGINE_set_DSA() */ |
|
130 extern DSA_METHOD *t4_DSA(void); |
|
131 |
|
132 /* Static variables */ |
|
133 /* This can't be const as NID*ctr is inserted when the engine is initialized */ |
|
134 static int t4_cipher_nids[] = { |
|
135 #ifndef OPENSSL_NO_DES |
|
136 /* Must be at end of list (see t4_des_cipher_count in t4_bind() */ |
|
137 NID_des_cbc, NID_des_ede3_cbc, NID_des_ecb, NID_des_ede3_ecb, |
|
138 #endif |
|
139 }; |
|
140 static const int t4_des_cipher_count = 4; |
|
141 static int t4_cipher_count = |
|
142 (sizeof (t4_cipher_nids) / sizeof (t4_cipher_nids[0])); |
|
143 |
|
144 |
|
145 /* |
|
146 * Cipher Algorithms |
|
147 * |
|
148 * OpenSSL's libcrypto EVP stuff. This is how this engine gets wired to EVP. |
|
149 * EVP_CIPHER is defined in evp.h. To maintain binary compatibility the |
|
150 * definition cannot be modified. |
|
151 * Stuff specific to the t4 engine is kept in t4_cipher_ctx_t, which is |
|
152 * pointed to by cipher_data or md_data |
|
153 * |
|
154 * Fields: nid, block_size, key_len, iv_len, flags, |
|
155 * init(), do_cipher(), cleanup(), |
|
156 * ctx_size, |
|
157 * set_asn1_parameters(), get_asn1_parameters(), ctrl(), app_data |
|
158 */ |
|
159 |
|
160 |
|
161 #ifndef OPENSSL_NO_DES |
|
162 extern const EVP_CIPHER t4_des_cbc; |
|
163 extern const EVP_CIPHER t4_des3_cbc; |
|
164 extern const EVP_CIPHER t4_des_ecb; |
|
165 extern const EVP_CIPHER t4_des3_ecb; |
|
166 #endif /* OPENSSL_NO_DES */ |
|
167 |
|
168 |
|
169 /* |
|
170 * Utility Functions |
|
171 */ |
|
172 |
|
173 /* |
|
174 * Set des_present and montmul_present to B_FALSE or B_TRUE |
|
175 * depending on whether the current SPARC processor supports DES |
|
176 * and MONTMUL, respectively. |
|
177 */ |
|
178 static void |
|
179 t4_instructions_present(_Bool *des_present, _Bool *montmul_present) |
|
180 { |
|
181 #ifdef OPENSSL_NO_DES |
|
182 #undef AV_SPARC_DES |
|
183 #define AV_SPARC_DES 0 |
|
184 #endif |
|
185 uint_t ui; |
|
186 |
|
187 (void) getisax(&ui, 1); |
|
188 *des_present = ((ui & AV_SPARC_DES) != 0); |
|
189 *montmul_present = ((ui & AV_SPARC_MONT) != 0); |
|
190 } |
|
191 |
|
192 |
|
193 /* |
|
194 * Cipher functions |
|
195 */ |
|
196 |
|
197 |
|
198 /* |
|
199 * Registered by the ENGINE with ENGINE_set_ciphers(). |
|
200 * Finds out how to deal with a particular cipher NID in the ENGINE. |
|
201 */ |
|
202 /* ARGSUSED */ |
|
203 static int |
|
204 t4_get_all_ciphers(ENGINE *e, const EVP_CIPHER **cipher, |
|
205 const int **nids, int nid) |
|
206 { |
|
207 if (cipher == NULL) { /* return a list of all supported ciphers */ |
|
208 *nids = (t4_cipher_count > 0) ? t4_cipher_nids : NULL; |
|
209 return (t4_cipher_count); |
|
210 } |
|
211 |
|
212 switch (nid) { |
|
213 #ifndef OPENSSL_NO_DES |
|
214 case NID_des_cbc: |
|
215 *cipher = &t4_des_cbc; |
|
216 break; |
|
217 case NID_des_ede3_cbc: |
|
218 *cipher = &t4_des3_cbc; |
|
219 break; |
|
220 case NID_des_ecb: |
|
221 *cipher = &t4_des_ecb; |
|
222 break; |
|
223 case NID_des_ede3_ecb: |
|
224 *cipher = &t4_des3_ecb; |
|
225 break; |
|
226 #endif /* !OPENSSL_NO_DES */ |
|
227 default: |
|
228 /* cipher not supported */ |
|
229 *cipher = NULL; |
|
230 return (0); |
|
231 } |
|
232 |
|
233 return (1); |
|
234 } |
|
235 |
|
236 |
|
237 /* |
|
238 * Is the t4 engine available? |
|
239 * Passed to ENGINE_set_init_function(). |
|
240 */ |
|
241 /* ARGSUSED */ |
|
242 static int |
|
243 t4_init(ENGINE *e) |
|
244 { |
|
245 return (1); |
|
246 } |
|
247 |
|
248 |
|
249 /* Passed to ENGINE_set_destroy_function(). */ |
|
250 /* ARGSUSED */ |
|
251 static int |
|
252 t4_destroy(ENGINE *e) |
|
253 { |
|
254 ERR_unload_t4_strings(); |
|
255 return (1); |
|
256 } |
|
257 |
|
258 |
|
259 /* |
|
260 * Called by t4_bind_helper(). |
|
261 * Note: too early to use T4err() functions on errors. |
|
262 */ |
|
263 /* ARGSUSED */ |
|
264 static int |
|
265 t4_bind(ENGINE *e) |
|
266 { |
|
267 _Bool des_engage, montmul_engage; |
|
268 |
|
269 t4_instructions_present(&des_engage, &montmul_engage); |
|
270 #ifdef DEBUG_T4 |
|
271 (void) fprintf(stderr, |
|
272 "t4_bind: engage des=%d\n", des_engage); |
|
273 #endif |
|
274 #ifndef OPENSSL_NO_DES |
|
275 if (!des_engage) { /* Remove DES ciphers from list */ |
|
276 t4_cipher_count -= t4_des_cipher_count; |
|
277 } |
|
278 #endif |
|
279 |
|
280 #ifdef DEBUG_T4 |
|
281 (void) fprintf(stderr, "t4_cipher_count = %d; t4_cipher_nids[] =\n", |
|
282 t4_cipher_count); |
|
283 for (int i = 0; i < t4_cipher_count; ++i) { |
|
284 (void) fprintf(stderr, " %d", t4_cipher_nids[i]); |
|
285 } |
|
286 (void) fprintf(stderr, "\n"); |
|
287 #endif /* DEBUG_T4 */ |
|
288 |
|
289 /* Register T4 engine ID, name, and functions */ |
|
290 if (!ENGINE_set_id(e, ENGINE_T4_ID) || |
|
291 !ENGINE_set_name(e, |
|
292 des_engage ? ENGINE_T4_NAME: ENGINE_NO_T4_NAME) || |
|
293 !ENGINE_set_init_function(e, t4_init) || |
|
294 (des_engage && !ENGINE_set_ciphers(e, t4_get_all_ciphers)) || |
|
295 #ifndef OPENSSL_NO_RSA |
|
296 (montmul_engage && !ENGINE_set_RSA(e, t4_RSA())) || |
|
297 #endif /* OPENSSL_NO_RSA */ |
|
298 #ifndef OPENSSL_NO_DH |
|
299 (montmul_engage && !ENGINE_set_DH(e, t4_DH())) || |
|
300 #endif /* OPENSSL_NO_DH */ |
|
301 #ifndef OPENSSL_NO_DSA |
|
302 (montmul_engage && !ENGINE_set_DSA(e, t4_DSA())) || |
|
303 #endif /* OPENSSL_NO_DSA */ |
|
304 !ENGINE_set_destroy_function(e, t4_destroy)) { |
|
305 return (0); |
|
306 } |
|
307 |
|
308 return (1); |
|
309 } |
|
310 |
|
311 |
|
312 /* |
|
313 * Called by ENGINE_load_t4(). |
|
314 * Note: too early to use T4err() functions on errors. |
|
315 */ |
|
316 static int |
|
317 t4_bind_helper(ENGINE *e, const char *id) |
|
318 { |
|
319 if (id != NULL && (strcmp(id, ENGINE_T4_ID) != 0)) { |
|
320 (void) fprintf(stderr, "T4: bad t4 engine ID\n"); |
|
321 return (0); |
|
322 } |
|
323 if (!t4_bind(e)) { |
|
324 (void) fprintf(stderr, |
|
325 "T4: failed to bind t4 engine\n"); |
|
326 return (0); |
|
327 } |
|
328 |
|
329 return (1); |
|
330 } |
|
331 |
|
332 |
|
333 #ifdef DYNAMIC_ENGINE |
|
334 IMPLEMENT_DYNAMIC_CHECK_FN() |
|
335 IMPLEMENT_DYNAMIC_BIND_FN(t4_bind_helper) |
|
336 #endif /* DYNAMIC_ENGINE */ |
|
337 #endif /* COMPILE_HW_T4 */ |
|
338 #endif /* !OPENSSL_NO_HW */ |
|