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 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
|
22 */ |
|
23 |
|
24 #include <sys/types.h> |
|
25 #include <sys/stat.h> |
|
26 #include <string.h> |
|
27 #include <fcntl.h> |
|
28 #include <pthread.h> |
|
29 #include <errno.h> |
|
30 #include <cryptoutil.h> |
|
31 #include <sys/crypto/ioctl.h> |
|
32 #include <sys/crypto/api.h> |
|
33 #include <openssl/bio.h> |
|
34 #include <openssl/aes.h> |
|
35 #include <openssl/engine.h> |
|
36 #include <security/cryptoki.h> |
|
37 |
|
38 #define DEVCRYPTO_LIB_NAME "devcrypto engine" |
|
39 #include "e_devcrypto_err.c" |
|
40 |
|
41 /* DEVCRYPTO CONTEXT */ |
|
42 typedef struct devcrypto_ctx { |
|
43 uint_t session_id; |
|
44 } devcrypto_ctx_t; |
|
45 |
|
46 /* Index for the supported ciphers */ |
|
47 typedef enum { |
|
48 DEV_DES_CBC, |
|
49 DEV_DES3_CBC, |
|
50 DEV_DES_ECB, |
|
51 DEV_DES3_ECB, |
|
52 DEV_RC4, |
|
53 DEV_AES_128_CBC, |
|
54 DEV_AES_192_CBC, |
|
55 DEV_AES_256_CBC, |
|
56 DEV_AES_128_ECB, |
|
57 DEV_AES_192_ECB, |
|
58 DEV_AES_256_ECB, |
|
59 DEV_BLOWFISH_CBC, |
|
60 DEV_AES_128_CTR, |
|
61 DEV_AES_192_CTR, |
|
62 DEV_AES_256_CTR, |
|
63 DEV_CIPHER_MAX |
|
64 } DEV_CIPHER_ID; |
|
65 |
|
66 typedef struct devcrypto_cipher { |
|
67 DEV_CIPHER_ID id; |
|
68 int nid; |
|
69 int iv_len; |
|
70 int min_key_len; |
|
71 int max_key_len; |
|
72 CK_KEY_TYPE key_type; |
|
73 CK_MECHANISM_TYPE mech_type; |
|
74 unsigned long flags; |
|
75 crypto_mech_type_t pn_internal_number; |
|
76 } devcrypto_cipher_t; |
|
77 |
|
78 |
|
79 /* Constants used when creating the ENGINE */ |
|
80 static const char *ENGINE_DEVCRYPTO_ID = "devcrypto"; |
|
81 static const char *ENGINE_DEVCRYPTO_NAME = "/dev/crypto engine support"; |
|
82 static const char *CRYPTO_DEVICE = "/dev/crypto"; |
|
83 |
|
84 /* static variables */ |
|
85 static int kernel_fd = -1; |
|
86 static int kernel_fd_ref = 0; |
|
87 static int slot_count = 0; |
|
88 static CK_SLOT_ID *kernel_provider_id = NULL; |
|
89 static int cipher_count = 0; |
|
90 static int *cipher_nids = NULL; |
|
91 pthread_mutex_t *kernel_fd_lock; |
|
92 |
|
93 /* |
|
94 * Cipher Table for all supported symmetric ciphers. |
|
95 */ |
|
96 static devcrypto_cipher_t cipher_table[] = { |
|
97 /* id, nid, iv_len, min_, max_key_len, */ |
|
98 /* key_type, mech_type, flags, pn_internal_number */ |
|
99 { DEV_DES_CBC, NID_des_cbc, 8, 8, 8, |
|
100 CKK_DES, CKM_DES_CBC, 0, CRYPTO_MECH_INVALID}, |
|
101 { DEV_DES3_CBC, NID_des_ede3_cbc, 8, 24, 24, |
|
102 CKK_DES3, CKM_DES3_CBC, 0, CRYPTO_MECH_INVALID}, |
|
103 { DEV_DES_ECB, NID_des_ecb, 0, 8, 8, |
|
104 CKK_DES, CKM_DES_ECB, 0, CRYPTO_MECH_INVALID}, |
|
105 { DEV_DES3_ECB, NID_des_ede3_ecb, 0, 24, 24, |
|
106 CKK_DES3, CKM_DES3_ECB, 0, CRYPTO_MECH_INVALID}, |
|
107 { DEV_RC4, NID_rc4, 0, 16, 256, |
|
108 CKK_RC4, CKM_RC4, 0, CRYPTO_MECH_INVALID}, |
|
109 { DEV_AES_128_CBC, NID_aes_128_cbc, 16, 16, 16, |
|
110 CKK_AES, CKM_AES_CBC, 0, CRYPTO_MECH_INVALID}, |
|
111 { DEV_AES_192_CBC, NID_aes_192_cbc, 16, 24, 24, |
|
112 CKK_AES, CKM_AES_CBC, 0, CRYPTO_MECH_INVALID}, |
|
113 { DEV_AES_256_CBC, NID_aes_256_cbc, 16, 32, 32, |
|
114 CKK_AES, CKM_AES_CBC, 0, CRYPTO_MECH_INVALID}, |
|
115 { DEV_AES_128_ECB, NID_aes_128_ecb, 0, 16, 16, |
|
116 CKK_AES, CKM_AES_ECB, 0, CRYPTO_MECH_INVALID}, |
|
117 { DEV_AES_192_ECB, NID_aes_192_ecb, 0, 24, 24, |
|
118 CKK_AES, CKM_AES_ECB, 0, CRYPTO_MECH_INVALID}, |
|
119 { DEV_AES_256_ECB, NID_aes_256_ecb, 0, 32, 32, |
|
120 CKK_AES, CKM_AES_ECB, 0, CRYPTO_MECH_INVALID}, |
|
121 { DEV_BLOWFISH_CBC, NID_bf_cbc, 8, 16, 16, |
|
122 CKK_BLOWFISH, CKM_BLOWFISH_CBC, 0, CRYPTO_MECH_INVALID}, |
|
123 { DEV_AES_128_CTR, NID_aes_128_ctr, 16, 16, 16, |
|
124 CKK_AES, CKM_AES_CTR, EVP_CIPH_NO_PADDING, |
|
125 CRYPTO_MECH_INVALID}, |
|
126 { DEV_AES_192_CTR, NID_aes_192_ctr, 16, 24, 24, |
|
127 CKK_AES, CKM_AES_CTR, EVP_CIPH_NO_PADDING, |
|
128 CRYPTO_MECH_INVALID}, |
|
129 { DEV_AES_256_CTR, NID_aes_256_ctr, 16, 32, 32, |
|
130 CKK_AES, CKM_AES_CTR, EVP_CIPH_NO_PADDING, |
|
131 CRYPTO_MECH_INVALID}, |
|
132 }; |
|
133 |
|
134 |
|
135 /* Formal declaration for functions in EVP_CIPHER structure */ |
|
136 static int devcrypto_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
|
137 const unsigned char *iv, int enc); |
|
138 static int devcrypto_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
|
139 const unsigned char *in, size_t inl); |
|
140 static int devcrypto_cipher_cleanup(EVP_CIPHER_CTX *ctx); |
|
141 |
|
142 /* |
|
143 * Cipher Algorithms |
|
144 * |
|
145 * OpenSSL's libcrypto EVP stuff. This is how this engine gets wired to EVP. |
|
146 * EVP_CIPHER is defined in evp.h. To maintain binary compatibility the |
|
147 * definition cannot be modified. |
|
148 * Stuff specific to the devcrypto engine is kept in devcrypto_ctx_t, which is |
|
149 * pointed to by cipher_data or md_data. |
|
150 * |
|
151 * Fields: nid, block_size, key_len, iv_len, flags, |
|
152 * init(), do_cipher(), cleanup(), |
|
153 * ctx_size, |
|
154 * set_asn1_parameters(), get_asn1_parameters(), ctrl(), app_data |
|
155 */ |
|
156 static const EVP_CIPHER dev_des_cbc = { |
|
157 NID_des_cbc, |
|
158 8, 8, 8, |
|
159 EVP_CIPH_CBC_MODE, |
|
160 devcrypto_cipher_init, |
|
161 devcrypto_cipher_do_cipher, |
|
162 devcrypto_cipher_cleanup, |
|
163 sizeof (devcrypto_ctx_t), |
|
164 EVP_CIPHER_set_asn1_iv, |
|
165 EVP_CIPHER_get_asn1_iv, |
|
166 NULL |
|
167 }; |
|
168 |
|
169 static const EVP_CIPHER dev_3des_cbc = { |
|
170 NID_des_ede3_cbc, |
|
171 8, 24, 8, |
|
172 EVP_CIPH_CBC_MODE, |
|
173 devcrypto_cipher_init, |
|
174 devcrypto_cipher_do_cipher, |
|
175 devcrypto_cipher_cleanup, |
|
176 sizeof (devcrypto_ctx_t), |
|
177 EVP_CIPHER_set_asn1_iv, |
|
178 EVP_CIPHER_get_asn1_iv, |
|
179 NULL |
|
180 }; |
|
181 |
|
182 /* |
|
183 * ECB modes don't use an Initial Vector, therefore set_asn1_parameters and |
|
184 * get_asn1_parameters fields are set to NULL. |
|
185 */ |
|
186 static const EVP_CIPHER dev_des_ecb = { |
|
187 NID_des_ecb, |
|
188 8, 8, 8, |
|
189 EVP_CIPH_ECB_MODE, |
|
190 devcrypto_cipher_init, |
|
191 devcrypto_cipher_do_cipher, |
|
192 devcrypto_cipher_cleanup, |
|
193 sizeof (devcrypto_ctx_t), |
|
194 NULL, |
|
195 NULL, |
|
196 NULL |
|
197 }; |
|
198 |
|
199 static const EVP_CIPHER dev_3des_ecb = { |
|
200 NID_des_ede3_ecb, |
|
201 8, 24, 8, |
|
202 EVP_CIPH_ECB_MODE, |
|
203 devcrypto_cipher_init, |
|
204 devcrypto_cipher_do_cipher, |
|
205 devcrypto_cipher_cleanup, |
|
206 sizeof (devcrypto_ctx_t), |
|
207 NULL, |
|
208 NULL, |
|
209 NULL |
|
210 }; |
|
211 |
|
212 static const EVP_CIPHER dev_rc4 = { |
|
213 NID_rc4, |
|
214 1, 16, 0, |
|
215 EVP_CIPH_VARIABLE_LENGTH, |
|
216 devcrypto_cipher_init, |
|
217 devcrypto_cipher_do_cipher, |
|
218 devcrypto_cipher_cleanup, |
|
219 sizeof (devcrypto_ctx_t), |
|
220 NULL, |
|
221 NULL, |
|
222 NULL |
|
223 }; |
|
224 |
|
225 static const EVP_CIPHER dev_aes_128_cbc = { |
|
226 NID_aes_128_cbc, |
|
227 16, 16, 16, |
|
228 EVP_CIPH_CBC_MODE, |
|
229 devcrypto_cipher_init, |
|
230 devcrypto_cipher_do_cipher, |
|
231 devcrypto_cipher_cleanup, |
|
232 sizeof (devcrypto_ctx_t), |
|
233 EVP_CIPHER_set_asn1_iv, |
|
234 EVP_CIPHER_get_asn1_iv, |
|
235 NULL |
|
236 }; |
|
237 |
|
238 static const EVP_CIPHER dev_aes_192_cbc = { |
|
239 NID_aes_192_cbc, |
|
240 16, 24, 16, |
|
241 EVP_CIPH_CBC_MODE, |
|
242 devcrypto_cipher_init, |
|
243 devcrypto_cipher_do_cipher, |
|
244 devcrypto_cipher_cleanup, |
|
245 sizeof (devcrypto_ctx_t), |
|
246 EVP_CIPHER_set_asn1_iv, |
|
247 EVP_CIPHER_get_asn1_iv, |
|
248 NULL |
|
249 }; |
|
250 |
|
251 static const EVP_CIPHER dev_aes_256_cbc = { |
|
252 NID_aes_256_cbc, |
|
253 16, 32, 16, |
|
254 EVP_CIPH_CBC_MODE, |
|
255 devcrypto_cipher_init, |
|
256 devcrypto_cipher_do_cipher, |
|
257 devcrypto_cipher_cleanup, |
|
258 sizeof (devcrypto_ctx_t), |
|
259 EVP_CIPHER_set_asn1_iv, |
|
260 EVP_CIPHER_get_asn1_iv, |
|
261 NULL |
|
262 }; |
|
263 |
|
264 |
|
265 /* |
|
266 * ECB modes don't use IV, therefore set_asn1_parameters and |
|
267 * get_asn1_parameters are set to NULL. |
|
268 */ |
|
269 static const EVP_CIPHER dev_aes_128_ecb = { |
|
270 NID_aes_128_ecb, |
|
271 16, 16, 0, |
|
272 EVP_CIPH_ECB_MODE, |
|
273 devcrypto_cipher_init, |
|
274 devcrypto_cipher_do_cipher, |
|
275 devcrypto_cipher_cleanup, |
|
276 sizeof (devcrypto_ctx_t), |
|
277 NULL, |
|
278 NULL, |
|
279 NULL |
|
280 }; |
|
281 |
|
282 static const EVP_CIPHER dev_aes_192_ecb = { |
|
283 NID_aes_192_ecb, |
|
284 16, 24, 0, |
|
285 EVP_CIPH_ECB_MODE, |
|
286 devcrypto_cipher_init, |
|
287 devcrypto_cipher_do_cipher, |
|
288 devcrypto_cipher_cleanup, |
|
289 sizeof (devcrypto_ctx_t), |
|
290 NULL, |
|
291 NULL, |
|
292 NULL |
|
293 }; |
|
294 |
|
295 static const EVP_CIPHER dev_aes_256_ecb = { |
|
296 NID_aes_256_ecb, |
|
297 16, 32, 0, |
|
298 EVP_CIPH_ECB_MODE, |
|
299 devcrypto_cipher_init, |
|
300 devcrypto_cipher_do_cipher, |
|
301 devcrypto_cipher_cleanup, |
|
302 sizeof (devcrypto_ctx_t), |
|
303 NULL, |
|
304 NULL, |
|
305 NULL |
|
306 }; |
|
307 |
|
308 static const EVP_CIPHER dev_bf_cbc = { |
|
309 NID_bf_cbc, |
|
310 8, 16, 8, |
|
311 EVP_CIPH_VARIABLE_LENGTH, |
|
312 devcrypto_cipher_init, |
|
313 devcrypto_cipher_do_cipher, |
|
314 devcrypto_cipher_cleanup, |
|
315 sizeof (devcrypto_ctx_t), |
|
316 EVP_CIPHER_set_asn1_iv, |
|
317 EVP_CIPHER_get_asn1_iv, |
|
318 NULL |
|
319 }; |
|
320 |
|
321 |
|
322 /* |
|
323 * NID_undef's will be changed for AES counter mode, as soon they are created. |
|
324 */ |
|
325 static EVP_CIPHER dev_aes_128_ctr = { |
|
326 NID_aes_128_ctr, |
|
327 16, 16, 16, |
|
328 EVP_CIPH_CTR_MODE, |
|
329 devcrypto_cipher_init, |
|
330 devcrypto_cipher_do_cipher, |
|
331 devcrypto_cipher_cleanup, |
|
332 sizeof (devcrypto_ctx_t), |
|
333 EVP_CIPHER_set_asn1_iv, |
|
334 EVP_CIPHER_get_asn1_iv, |
|
335 NULL |
|
336 }; |
|
337 |
|
338 static EVP_CIPHER dev_aes_192_ctr = { |
|
339 NID_aes_192_ctr, |
|
340 16, 24, 16, |
|
341 EVP_CIPH_CTR_MODE, |
|
342 devcrypto_cipher_init, |
|
343 devcrypto_cipher_do_cipher, |
|
344 devcrypto_cipher_cleanup, |
|
345 sizeof (devcrypto_ctx_t), |
|
346 EVP_CIPHER_set_asn1_iv, |
|
347 EVP_CIPHER_get_asn1_iv, |
|
348 NULL |
|
349 }; |
|
350 |
|
351 static EVP_CIPHER dev_aes_256_ctr = { |
|
352 NID_aes_256_ctr, |
|
353 16, 32, 16, |
|
354 EVP_CIPH_CTR_MODE, |
|
355 devcrypto_cipher_init, |
|
356 devcrypto_cipher_do_cipher, |
|
357 devcrypto_cipher_cleanup, |
|
358 sizeof (devcrypto_ctx_t), |
|
359 EVP_CIPHER_set_asn1_iv, |
|
360 EVP_CIPHER_get_asn1_iv, |
|
361 NULL |
|
362 }; |
|
363 |
|
364 |
|
365 /* |
|
366 * Open the /dev/crypto device |
|
367 */ |
|
368 static int |
|
369 devcrypto_open(void) |
|
370 { |
|
371 int fd = -1; |
|
372 |
|
373 if (kernel_fd != -1) { /* already open */ |
|
374 (void) pthread_mutex_lock(kernel_fd_lock); |
|
375 kernel_fd_ref++; |
|
376 (void) pthread_mutex_unlock(kernel_fd_lock); |
|
377 return (1); |
|
378 } |
|
379 |
|
380 (void) pthread_mutex_lock(kernel_fd_lock); |
|
381 fd = open(CRYPTO_DEVICE, O_RDWR); |
|
382 if (fd == -1) { |
|
383 #ifdef DEBUG |
|
384 (void) fprintf(stderr, |
|
385 "libdevcrypto: open /dev/crypto failed, errno=%x\n", |
|
386 errno); |
|
387 #endif |
|
388 (void) pthread_mutex_unlock(kernel_fd_lock); |
|
389 return (0); |
|
390 } |
|
391 |
|
392 if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { |
|
393 #ifdef DEBUG |
|
394 (void) fprintf(stderr, "libdevcrypto: failed to fcntl\n"); |
|
395 #endif |
|
396 (void) close(fd); |
|
397 (void) pthread_mutex_unlock(kernel_fd_lock); |
|
398 return (0); |
|
399 } |
|
400 |
|
401 kernel_fd = fd; |
|
402 kernel_fd_ref++; |
|
403 (void) pthread_mutex_unlock(kernel_fd_lock); |
|
404 return (1); |
|
405 } |
|
406 |
|
407 |
|
408 /* |
|
409 * This function gets the total number of hardware providers presented in |
|
410 * the system first. If there is any hardware providers, then it will get |
|
411 * the kernel provider id for each hardware slot also. |
|
412 */ |
|
413 static int |
|
414 devcrypto_get_slot_info(void) |
|
415 { |
|
416 crypto_get_provider_list_t *pl = NULL; |
|
417 int ret = 1; |
|
418 int r; |
|
419 int i; |
|
420 |
|
421 /* Already have the information */ |
|
422 if (kernel_provider_id != NULL) |
|
423 return (1); |
|
424 |
|
425 /* Find out how many hardware slots are presented. */ |
|
426 pl = OPENSSL_malloc(sizeof (crypto_get_provider_list_t)); |
|
427 if (pl == NULL) |
|
428 return (0); |
|
429 |
|
430 pl->pl_count = 0; |
|
431 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) { |
|
432 if (errno != EINTR) |
|
433 break; |
|
434 } |
|
435 if (r < 0 || pl->pl_return_value != CRYPTO_SUCCESS) { |
|
436 #ifdef DEBUG |
|
437 (void) fprintf(stderr, "libdevcrypto:CRYPTO_GET_PROVIDER_LIST:" |
|
438 "ret (r) = 0x%x, (rv) = 0x%x\n", r, pl->pl_return_value); |
|
439 #endif /* DEBUG */ |
|
440 ret = 0; |
|
441 goto out; |
|
442 } |
|
443 |
|
444 slot_count = pl->pl_count; |
|
445 if (slot_count == 0) { |
|
446 #ifdef DEBUG |
|
447 (void) fprintf(stderr, "libdevcrypto: no hw providers\n"); |
|
448 #endif /* DEBUG */ |
|
449 ret = 0; |
|
450 goto out; |
|
451 } |
|
452 |
|
453 /* Get the provider ID for each slot from kernel and save it */ |
|
454 kernel_provider_id = OPENSSL_malloc(sizeof (CK_SLOT_ID) * slot_count); |
|
455 if (kernel_provider_id == NULL) { |
|
456 ret = 0; |
|
457 goto out; |
|
458 } |
|
459 |
|
460 (void) OPENSSL_free(pl); |
|
461 pl = OPENSSL_malloc(slot_count * sizeof (crypto_get_provider_list_t)); |
|
462 if (pl == NULL) { |
|
463 ret = 0; |
|
464 goto out; |
|
465 } |
|
466 |
|
467 pl->pl_count = slot_count; |
|
468 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) { |
|
469 if (errno != EINTR) |
|
470 break; |
|
471 } |
|
472 if (r < 0 || (pl->pl_return_value != CRYPTO_SUCCESS)) { |
|
473 #ifdef DEBUG |
|
474 (void) fprintf(stderr, "libdevcrypto:CRYPTO_GET_PROVIDER_LIST:" |
|
475 "ret (r) = 0x%x, (rv) = 0x%x\n", r, pl->pl_return_value); |
|
476 #endif /* DEBUG */ |
|
477 ret = 0; |
|
478 goto out; |
|
479 } |
|
480 |
|
481 for (i = 0; i < slot_count; i++) { |
|
482 kernel_provider_id[i] = pl->pl_list[i].pe_provider_id; |
|
483 #ifdef DEBUG |
|
484 (void) fprintf(stderr, "libdevcrypto: i = %d, " |
|
485 "kernel_provider_id = %d\n", i, kernel_provider_id[i]); |
|
486 #endif /* DEBUG */ |
|
487 } |
|
488 |
|
489 out: |
|
490 if (pl != NULL) |
|
491 (void) OPENSSL_free(pl); |
|
492 |
|
493 if (ret == 0 && kernel_provider_id != NULL) { |
|
494 (void) OPENSSL_free(kernel_provider_id); |
|
495 kernel_provider_id = NULL; |
|
496 } |
|
497 |
|
498 return (ret); |
|
499 } |
|
500 |
|
501 |
|
502 /* |
|
503 * This function checks if the "nid" is already in the nid list. |
|
504 */ |
|
505 static int |
|
506 nid_in_list(int nid, int *nid_list, int count) |
|
507 { |
|
508 int i = 0; |
|
509 |
|
510 if (nid_list == NULL || count <= 0) |
|
511 return (0); |
|
512 |
|
513 while (i < count) { |
|
514 if (nid == nid_list[i]) |
|
515 break; |
|
516 i++; |
|
517 } |
|
518 return (i < count ? 1 : 0); |
|
519 } |
|
520 |
|
521 /* |
|
522 * This function is to get all the ciphers supported by hardware providers. |
|
523 * If this function is successfully completed, then the following 2 global |
|
524 * variables will be set. |
|
525 * cipher_count - the number of ciphers found in all hardware providers. |
|
526 * cipher_nids - the nid list for all the ciphers. |
|
527 */ |
|
528 static int |
|
529 devcrypto_get_hw_ciphers(void) |
|
530 { |
|
531 crypto_get_provider_mechanism_info_t mechinfo; |
|
532 int max_cipher_count; |
|
533 int *tmp_nids = NULL; |
|
534 const char *mech_string; |
|
535 int r; |
|
536 int i, j; |
|
537 |
|
538 if (slot_count <= 0) /* no hardware provider */ |
|
539 return (0); |
|
540 |
|
541 max_cipher_count = slot_count * DEV_CIPHER_MAX + 1; |
|
542 tmp_nids = OPENSSL_malloc(max_cipher_count * sizeof (int)); |
|
543 if (tmp_nids == NULL) { |
|
544 /* not enough memory */ |
|
545 goto failed; |
|
546 } |
|
547 |
|
548 for (i = 0; i < slot_count; i++) { |
|
549 mechinfo.mi_provider_id = kernel_provider_id[i]; |
|
550 for (j = 0; j < DEV_CIPHER_MAX; j++) { |
|
551 mech_string = |
|
552 pkcs11_mech2str(cipher_table[j].mech_type); |
|
553 if (mech_string == NULL) { |
|
554 continue; /* shouldn't happen; skip it */ |
|
555 } |
|
556 |
|
557 (void) strlcpy(mechinfo.mi_mechanism_name, |
|
558 mech_string, CRYPTO_MAX_MECH_NAME); |
|
559 while ((r = ioctl(kernel_fd, |
|
560 CRYPTO_GET_PROVIDER_MECHANISM_INFO, |
|
561 &mechinfo)) < 0) { |
|
562 if (errno != EINTR) |
|
563 break; |
|
564 } |
|
565 if (r < 0) { |
|
566 goto failed; |
|
567 } |
|
568 |
|
569 if (mechinfo.mi_return_value == CRYPTO_SUCCESS) { |
|
570 /* |
|
571 * Found this mechanism in hardware providers. |
|
572 * If it is not in the nid list yet, add it. |
|
573 */ |
|
574 if (!nid_in_list(cipher_table[j].nid, |
|
575 tmp_nids, cipher_count)) { |
|
576 tmp_nids[cipher_count] = |
|
577 cipher_table[j].nid; |
|
578 cipher_count++; |
|
579 } |
|
580 } |
|
581 } |
|
582 } |
|
583 |
|
584 if (cipher_count > 0) { |
|
585 cipher_nids = tmp_nids; |
|
586 } |
|
587 |
|
588 return (1); |
|
589 |
|
590 failed: |
|
591 if (r < 0 || cipher_count == 0) { |
|
592 if (tmp_nids != NULL) |
|
593 OPENSSL_free(tmp_nids); |
|
594 } |
|
595 return (0); |
|
596 } |
|
597 |
|
598 /* |
|
599 * Registered by the ENGINE when used to find out how to deal with |
|
600 * a particular NID in the ENGINE. This says what we'll do at the |
|
601 * top level - note, that list is restricted by what we answer with. |
|
602 */ |
|
603 static int |
|
604 devcrypto_get_all_ciphers(ENGINE *e, const EVP_CIPHER **cipher, |
|
605 const int **nids, int nid) |
|
606 { |
|
607 if (!cipher) { |
|
608 *nids = (cipher_count > 0) ? cipher_nids : NULL; |
|
609 return (cipher_count); |
|
610 } |
|
611 |
|
612 switch (nid) { |
|
613 case NID_des_cbc: |
|
614 *cipher = &dev_des_cbc; |
|
615 break; |
|
616 case NID_des_ede3_cbc: |
|
617 *cipher = &dev_3des_cbc; |
|
618 break; |
|
619 case NID_des_ecb: |
|
620 *cipher = &dev_des_ecb; |
|
621 break; |
|
622 case NID_des_ede3_ecb: |
|
623 *cipher = &dev_3des_ecb; |
|
624 break; |
|
625 case NID_rc4: |
|
626 *cipher = &dev_rc4; |
|
627 break; |
|
628 case NID_aes_128_cbc: |
|
629 *cipher = &dev_aes_128_cbc; |
|
630 break; |
|
631 case NID_aes_192_cbc: |
|
632 *cipher = &dev_aes_192_cbc; |
|
633 break; |
|
634 case NID_aes_256_cbc: |
|
635 *cipher = &dev_aes_256_cbc; |
|
636 break; |
|
637 case NID_aes_128_ecb: |
|
638 *cipher = &dev_aes_128_ecb; |
|
639 break; |
|
640 case NID_aes_192_ecb: |
|
641 *cipher = &dev_aes_192_ecb; |
|
642 break; |
|
643 case NID_aes_256_ecb: |
|
644 *cipher = &dev_aes_256_ecb; |
|
645 break; |
|
646 case NID_bf_cbc: |
|
647 *cipher = &dev_bf_cbc; |
|
648 break; |
|
649 default: |
|
650 /* |
|
651 * We cannot put the NIDs for AES counter mode in separated |
|
652 * cases as above because they are not constants. |
|
653 */ |
|
654 if (nid == NID_aes_128_ctr) |
|
655 *cipher = &dev_aes_128_ctr; |
|
656 else if (nid == NID_aes_192_ctr) |
|
657 *cipher = &dev_aes_192_ctr; |
|
658 else if (nid == NID_aes_256_ctr) |
|
659 *cipher = &dev_aes_256_ctr; |
|
660 else |
|
661 *cipher = NULL; |
|
662 break; |
|
663 } |
|
664 |
|
665 return (*cipher != NULL); |
|
666 } |
|
667 |
|
668 |
|
669 static int |
|
670 get_cipher_id_by_nid(int nid) |
|
671 { |
|
672 int i; |
|
673 |
|
674 for (i = 0; i < DEV_CIPHER_MAX; i++) |
|
675 if (cipher_table[i].nid == nid) |
|
676 return (cipher_table[i].id); |
|
677 return (-1); |
|
678 } |
|
679 |
|
680 |
|
681 static int |
|
682 get_slotid_by_mechanism(const char *mech_string, CK_SLOT_ID *slot_id) |
|
683 { |
|
684 crypto_get_provider_mechanism_info_t mechanism_info; |
|
685 uint_t rv; |
|
686 int r; |
|
687 int i = 0; |
|
688 |
|
689 (void) strlcpy(mechanism_info.mi_mechanism_name, mech_string, |
|
690 CRYPTO_MAX_MECH_NAME); |
|
691 while (i < slot_count) { |
|
692 mechanism_info.mi_provider_id = kernel_provider_id[i]; |
|
693 while ((r = ioctl(kernel_fd, |
|
694 CRYPTO_GET_PROVIDER_MECHANISM_INFO, |
|
695 &mechanism_info)) < 0) { |
|
696 if (errno != EINTR) |
|
697 break; |
|
698 } |
|
699 if (r < 0) { |
|
700 return (0); /* ioctl function failed */ |
|
701 } |
|
702 rv = mechanism_info.mi_return_value; |
|
703 if (rv == 0) { /* found it */ |
|
704 *slot_id = kernel_provider_id[i]; |
|
705 return (1); |
|
706 } |
|
707 i++; |
|
708 } |
|
709 |
|
710 return (0); |
|
711 } |
|
712 |
|
713 |
|
714 static int |
|
715 devcrypto_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
|
716 const unsigned char *iv, int enc) |
|
717 { |
|
718 devcrypto_ctx_t *devc_ctx = ctx->cipher_data; |
|
719 crypto_encrypt_init_t encrypt_init; |
|
720 crypto_decrypt_init_t decrypt_init; |
|
721 crypto_open_session_t session; |
|
722 crypto_get_mechanism_number_t get_number; |
|
723 CK_AES_CTR_PARAMS aes_ctr_params; |
|
724 devcrypto_cipher_t *the_cipher; |
|
725 const char *mech_string; |
|
726 CK_SLOT_ID slot_id; |
|
727 int index; |
|
728 int r; |
|
729 uint_t rv = 0; |
|
730 |
|
731 if (key == NULL) { |
|
732 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_CIPHER_KEY); |
|
733 return (0); |
|
734 } |
|
735 |
|
736 /* get the cipher entry index in cipher_table from nid */ |
|
737 index = get_cipher_id_by_nid(ctx->cipher->nid); |
|
738 if (index < 0 || index >= DEV_CIPHER_MAX) { |
|
739 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_CIPHER_NID); |
|
740 return (0); |
|
741 } |
|
742 the_cipher = &cipher_table[index]; |
|
743 |
|
744 /* check key size */ |
|
745 if (ctx->cipher->iv_len < the_cipher->iv_len || |
|
746 ctx->key_len < the_cipher->min_key_len || |
|
747 ctx->key_len > the_cipher->max_key_len) { |
|
748 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_KEY_OR_IV_LEN_PROBLEM); |
|
749 return (0); |
|
750 } |
|
751 |
|
752 /* Set cipher flags, if any */ |
|
753 ctx->flags |= the_cipher->flags; |
|
754 |
|
755 /* get the mechanism string */ |
|
756 mech_string = pkcs11_mech2str(the_cipher->mech_type); |
|
757 if (mech_string == NULL) { |
|
758 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_MECH_STRING); |
|
759 return (0); |
|
760 } |
|
761 |
|
762 #ifdef DEBUG |
|
763 (void) fprintf(stderr, "libdevcrypto: mech_string=%s\n", mech_string); |
|
764 #endif |
|
765 |
|
766 /* Find the slot that supports this mechanism */ |
|
767 if (!get_slotid_by_mechanism(mech_string, &slot_id)) { |
|
768 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_FIND_SLOT_BY_MECH); |
|
769 #ifdef DEBUG |
|
770 (void) fprintf(stderr, |
|
771 "libdevcrypto: failed to find a slot with %s\n", |
|
772 mech_string); |
|
773 #endif |
|
774 return (0); |
|
775 } |
|
776 |
|
777 #ifdef DEBUG |
|
778 (void) fprintf(stderr, "libdevcrypto: found a slot with %s, " |
|
779 "slot_id = %d\n", mech_string, slot_id); |
|
780 #endif |
|
781 |
|
782 /* Open a session on this slot */ |
|
783 session.os_provider_id = slot_id; |
|
784 session.os_flags = CKF_RW_SESSION | CKF_SERIAL_SESSION; |
|
785 while ((r = ioctl(kernel_fd, CRYPTO_OPEN_SESSION, &session)) < 0) { |
|
786 if (errno != EINTR) |
|
787 break; |
|
788 } |
|
789 rv = session.os_return_value; |
|
790 if (r || rv) { |
|
791 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_OPEN_SESSION); |
|
792 #ifdef DEBUG |
|
793 (void) fprintf(stderr, |
|
794 "libdevcrypto:cipher_init:failed to open a session\n"); |
|
795 #endif /* DEBUG */ |
|
796 goto failed; |
|
797 } |
|
798 |
|
799 #ifdef DEBUG |
|
800 (void) fprintf(stderr, "libdevcrypto:cipher_init: open session = %d\n", |
|
801 session.os_session); |
|
802 #endif /* DEBUG */ |
|
803 |
|
804 /* save the session_id */ |
|
805 devc_ctx->session_id = session.os_session; |
|
806 |
|
807 /* |
|
808 * Get the kernel mechanism number for this mechanism, if it has not |
|
809 * been retrieved yet. |
|
810 */ |
|
811 if (the_cipher->pn_internal_number == CRYPTO_MECH_INVALID) { |
|
812 get_number.pn_mechanism_string = (char *)mech_string; |
|
813 get_number.pn_mechanism_len = strlen(mech_string) + 1; |
|
814 while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER, |
|
815 &get_number)) < 0) { |
|
816 if (errno != EINTR) |
|
817 break; |
|
818 } |
|
819 rv = get_number.pn_return_value; |
|
820 if (r || rv) { |
|
821 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, |
|
822 DEVC_R_GET_MECHANISM_NUMBER); |
|
823 #ifdef DEBUG |
|
824 (void) fprintf(stderr, "libdevcrypto:cipher_init: " |
|
825 "failed to get the kernel mech number.\n"); |
|
826 #endif /* DEBUG */ |
|
827 goto failed; |
|
828 } |
|
829 |
|
830 the_cipher->pn_internal_number = get_number.pn_internal_number; |
|
831 } |
|
832 |
|
833 /* Crypto Init */ |
|
834 if (ctx->encrypt) { |
|
835 encrypt_init.ei_session = session.os_session; |
|
836 encrypt_init.ei_key.ck_format = CRYPTO_KEY_RAW; |
|
837 encrypt_init.ei_key.ck_obj_id = 0; |
|
838 encrypt_init.ei_key.ck_data = (void *) key; |
|
839 encrypt_init.ei_key.ck_length = ctx->key_len * 8; |
|
840 encrypt_init.ei_mech.cm_type = the_cipher->pn_internal_number; |
|
841 |
|
842 if (ctx->cipher->nid == NID_aes_128_ctr || |
|
843 ctx->cipher->nid == NID_aes_192_ctr || |
|
844 ctx->cipher->nid == NID_aes_256_ctr) { |
|
845 encrypt_init.ei_mech.cm_param = |
|
846 (void *) (&aes_ctr_params); |
|
847 encrypt_init.ei_mech.cm_param_len = |
|
848 sizeof (aes_ctr_params); |
|
849 |
|
850 aes_ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8; |
|
851 OPENSSL_assert(ctx->cipher->iv_len == AES_BLOCK_SIZE); |
|
852 (void) memcpy(aes_ctr_params.cb, ctx->iv, |
|
853 AES_BLOCK_SIZE); |
|
854 } else { |
|
855 if (the_cipher->iv_len > 0) { |
|
856 encrypt_init.ei_mech.cm_param = |
|
857 (char *)ctx->iv; |
|
858 encrypt_init.ei_mech.cm_param_len = |
|
859 ctx->cipher->iv_len; |
|
860 } else { |
|
861 encrypt_init.ei_mech.cm_param = NULL; |
|
862 encrypt_init.ei_mech.cm_param_len = 0; |
|
863 } |
|
864 } |
|
865 |
|
866 while ((r = ioctl(kernel_fd, CRYPTO_ENCRYPT_INIT, |
|
867 &encrypt_init)) < 0) { |
|
868 if (errno != EINTR) |
|
869 break; |
|
870 } |
|
871 rv = encrypt_init.ei_return_value; |
|
872 |
|
873 } else { |
|
874 decrypt_init.di_session = session.os_session; |
|
875 decrypt_init.di_key.ck_format = CRYPTO_KEY_RAW; |
|
876 decrypt_init.di_key.ck_obj_id = 0; |
|
877 decrypt_init.di_key.ck_data = (void *) key; |
|
878 decrypt_init.di_key.ck_length = ctx->key_len * 8; |
|
879 decrypt_init.di_mech.cm_type = the_cipher->pn_internal_number; |
|
880 |
|
881 if (ctx->cipher->nid == NID_aes_128_ctr || |
|
882 ctx->cipher->nid == NID_aes_192_ctr || |
|
883 ctx->cipher->nid == NID_aes_256_ctr) { |
|
884 decrypt_init.di_mech.cm_param = |
|
885 (void *)(&aes_ctr_params); |
|
886 decrypt_init.di_mech.cm_param_len = |
|
887 sizeof (aes_ctr_params); |
|
888 aes_ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8; |
|
889 OPENSSL_assert(ctx->cipher->iv_len == AES_BLOCK_SIZE); |
|
890 (void) memcpy(aes_ctr_params.cb, ctx->iv, |
|
891 AES_BLOCK_SIZE); |
|
892 } else { |
|
893 if (the_cipher->iv_len > 0) { |
|
894 decrypt_init.di_mech.cm_param = |
|
895 (char *)ctx->iv; |
|
896 decrypt_init.di_mech.cm_param_len = |
|
897 ctx->cipher->iv_len; |
|
898 } else { |
|
899 decrypt_init.di_mech.cm_param = NULL; |
|
900 decrypt_init.di_mech.cm_param_len = 0; |
|
901 } |
|
902 } |
|
903 |
|
904 while ((r = ioctl(kernel_fd, CRYPTO_DECRYPT_INIT, |
|
905 &decrypt_init)) < 0) { |
|
906 if (errno != EINTR) |
|
907 break; |
|
908 } |
|
909 rv = decrypt_init.di_return_value; |
|
910 } |
|
911 |
|
912 failed: |
|
913 if (r || rv) { |
|
914 if (ctx->encrypt) |
|
915 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_ENCRYPT_INIT); |
|
916 else |
|
917 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_DECRYPT_INIT); |
|
918 |
|
919 return (0); |
|
920 } |
|
921 |
|
922 return (1); |
|
923 } |
|
924 |
|
925 |
|
926 /* |
|
927 * ENCRYPT_UPDATE or DECRYPT_UPDATE |
|
928 */ |
|
929 static int |
|
930 devcrypto_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
|
931 const unsigned char *in, size_t inl) |
|
932 { |
|
933 crypto_encrypt_update_t encrypt_update; |
|
934 crypto_decrypt_update_t decrypt_update; |
|
935 devcrypto_ctx_t *devc_ctx = ctx->cipher_data; |
|
936 int r = 0, rv = 0; |
|
937 |
|
938 if (ctx->encrypt) { |
|
939 encrypt_update.eu_session = devc_ctx->session_id; |
|
940 encrypt_update.eu_databuf = (char *)in; |
|
941 encrypt_update.eu_datalen = inl; |
|
942 encrypt_update.eu_encrbuf = (char *)out; |
|
943 encrypt_update.eu_encrlen = inl; |
|
944 |
|
945 while ((r = ioctl(kernel_fd, CRYPTO_ENCRYPT_UPDATE, |
|
946 &encrypt_update)) < 0) { |
|
947 if (errno != EINTR) |
|
948 break; |
|
949 } |
|
950 rv = encrypt_update.eu_return_value; |
|
951 |
|
952 } else { /* decrypt */ |
|
953 decrypt_update.du_session = devc_ctx->session_id; |
|
954 decrypt_update.du_encrbuf = (char *)in; |
|
955 decrypt_update.du_encrlen = inl; |
|
956 decrypt_update.du_databuf = (char *)out; |
|
957 decrypt_update.du_datalen = inl; |
|
958 |
|
959 while ((r = ioctl(kernel_fd, CRYPTO_DECRYPT_UPDATE, |
|
960 &decrypt_update)) < 0) { |
|
961 if (errno != EINTR) |
|
962 break; |
|
963 } |
|
964 rv = decrypt_update.du_return_value; |
|
965 } |
|
966 |
|
967 if (r || rv) { |
|
968 if (ctx->encrypt) |
|
969 DEVCRYPTOerr(DEVC_F_CIPHER_DO_CIPHER, |
|
970 DEVC_R_ENCRYPT_UPDATE); |
|
971 else |
|
972 DEVCRYPTOerr(DEVC_F_CIPHER_DO_CIPHER, |
|
973 DEVC_R_DECRYPT_UPDATE); |
|
974 |
|
975 #ifdef DEBUG |
|
976 (void) fprintf(stderr, "libdevcrypto:crypto_do ret (r) = 0x%x," |
|
977 "crypto ret (rv) = 0x%x,", r, rv); |
|
978 #endif /* DEBUG */ |
|
979 return (0); |
|
980 } |
|
981 |
|
982 return (1); |
|
983 } |
|
984 |
|
985 |
|
986 /* |
|
987 * ENCRYPT_FINAL or DECRYPT_FINAL |
|
988 */ |
|
989 static int |
|
990 devcrypto_cipher_cleanup(EVP_CIPHER_CTX *ctx) |
|
991 { |
|
992 crypto_encrypt_final_t encrypt_final; |
|
993 crypto_decrypt_final_t decrypt_final; |
|
994 crypto_close_session_t session; |
|
995 devcrypto_ctx_t *devc_ctx = ctx->cipher_data; |
|
996 char buf[EVP_MAX_BLOCK_LENGTH]; |
|
997 int r; |
|
998 uint_t rv = 0; |
|
999 int ret = 1; |
|
1000 |
|
1001 if (ctx->encrypt) { |
|
1002 encrypt_final.ef_session = devc_ctx->session_id; |
|
1003 encrypt_final.ef_encrbuf = buf; |
|
1004 encrypt_final.ef_encrlen = sizeof (buf); |
|
1005 while ((r = ioctl(kernel_fd, CRYPTO_ENCRYPT_FINAL, |
|
1006 &encrypt_final)) < 0) { |
|
1007 if (errno != EINTR) |
|
1008 break; |
|
1009 } |
|
1010 rv = encrypt_final.ef_return_value; |
|
1011 |
|
1012 } else { |
|
1013 decrypt_final.df_session = devc_ctx->session_id; |
|
1014 decrypt_final.df_databuf = buf; |
|
1015 decrypt_final.df_datalen = sizeof (buf); |
|
1016 while ((r = ioctl(kernel_fd, CRYPTO_DECRYPT_FINAL, |
|
1017 &decrypt_final)) < 0) { |
|
1018 if (errno != EINTR) |
|
1019 break; |
|
1020 } |
|
1021 rv = decrypt_final.df_return_value; |
|
1022 } |
|
1023 |
|
1024 #ifdef DEBUG |
|
1025 if (ctx->encrypt) |
|
1026 (void) fprintf(stderr, "libdevcrypto:CRYPTO_ENCRYPT_FINAL " |
|
1027 "ret (r) = 0x%x, (rv) = 0x%x\n", r, rv); |
|
1028 else |
|
1029 (void) fprintf(stderr, "libdevcrypto:CRYPTO_DECRYPT_FINAL " |
|
1030 "ret (r) = 0x%x, (rv) = 0x%x\n", r, rv); |
|
1031 #endif /* DEBUG */ |
|
1032 |
|
1033 if (r || rv) { |
|
1034 if (ctx->encrypt) |
|
1035 DEVCRYPTOerr(DEVC_F_CIPHER_CLEANUP, |
|
1036 DEVC_R_ENCRYPT_FINAL); |
|
1037 else |
|
1038 DEVCRYPTOerr(DEVC_F_CIPHER_CLEANUP, |
|
1039 DEVC_R_DECRYPT_FINAL); |
|
1040 ret = 0; |
|
1041 } |
|
1042 |
|
1043 /* close the session */ |
|
1044 session.cs_session = devc_ctx->session_id; |
|
1045 while ((r = ioctl(kernel_fd, CRYPTO_CLOSE_SESSION, &session)) < 0) { |
|
1046 if (errno != EINTR) |
|
1047 break; |
|
1048 } |
|
1049 |
|
1050 #ifdef DEBUG |
|
1051 (void) fprintf(stderr, "libdevcrypto:CRYPTO_CLOSE_SESSION, " |
|
1052 "session id = %d ret (r) = 0x%x, crypto ret (rv) = 0x%x\n", |
|
1053 devc_ctx->session_id, r, rv); |
|
1054 #endif /* DEBUG */ |
|
1055 |
|
1056 if (r || rv) { |
|
1057 DEVCRYPTOerr(DEVC_F_CIPHER_CLEANUP, DEVC_R_CLOSE_SESSION); |
|
1058 ret = 0; |
|
1059 } |
|
1060 |
|
1061 return (ret); |
|
1062 } |
|
1063 |
|
1064 static void |
|
1065 devcrypto_cleanup(void) |
|
1066 { |
|
1067 if (kernel_fd == -1) |
|
1068 return; |
|
1069 |
|
1070 (void) pthread_mutex_lock(kernel_fd_lock); |
|
1071 kernel_fd_ref--; |
|
1072 (void) pthread_mutex_unlock(kernel_fd_lock); |
|
1073 |
|
1074 if (kernel_fd_ref == 0) { |
|
1075 (void) pthread_mutex_lock(kernel_fd_lock); |
|
1076 (void) close(kernel_fd); |
|
1077 kernel_fd = -1; |
|
1078 if (kernel_provider_id != NULL) { |
|
1079 OPENSSL_free(kernel_provider_id); |
|
1080 kernel_provider_id = NULL; |
|
1081 } |
|
1082 if (cipher_nids != NULL) { |
|
1083 OPENSSL_free(cipher_nids); |
|
1084 cipher_nids = NULL; |
|
1085 } |
|
1086 (void) pthread_mutex_unlock(kernel_fd_lock); |
|
1087 (void) pthread_mutex_destroy(kernel_fd_lock); |
|
1088 OPENSSL_free(kernel_fd_lock); |
|
1089 kernel_fd_lock = NULL; |
|
1090 } |
|
1091 } |
|
1092 |
|
1093 static int |
|
1094 devcrypto_destroy(ENGINE *e) |
|
1095 { |
|
1096 ERR_unload_devcrypto_strings(); |
|
1097 return (1); |
|
1098 } |
|
1099 |
|
1100 static int |
|
1101 devcrypto_finish(ENGINE *e) |
|
1102 { |
|
1103 devcrypto_cleanup(); |
|
1104 return (1); |
|
1105 } |
|
1106 |
|
1107 /* |
|
1108 * Set up the engine info and get the /dev/crypto engine ready. |
|
1109 */ |
|
1110 static int |
|
1111 devcrypto_bind(ENGINE *e) |
|
1112 { |
|
1113 #ifdef DEBUG |
|
1114 int i; |
|
1115 #endif |
|
1116 |
|
1117 /* Create a lock for the devcrypto device file descriptor */ |
|
1118 if (kernel_fd_lock == NULL) { |
|
1119 kernel_fd_lock = OPENSSL_malloc(sizeof (pthread_mutex_t)); |
|
1120 if (kernel_fd_lock == NULL) { |
|
1121 return (0); |
|
1122 } |
|
1123 |
|
1124 if (pthread_mutex_init(kernel_fd_lock, NULL) != 0) { |
|
1125 OPENSSL_free(kernel_fd_lock); |
|
1126 kernel_fd_lock = NULL; |
|
1127 return (0); |
|
1128 } |
|
1129 } |
|
1130 |
|
1131 /* Open the /dev/crypto device */ |
|
1132 if (devcrypto_open() == 0) { |
|
1133 pthread_mutex_destroy(kernel_fd_lock); |
|
1134 OPENSSL_free(kernel_fd_lock); |
|
1135 kernel_fd_lock = NULL; |
|
1136 return (0); |
|
1137 } |
|
1138 |
|
1139 /* Get all hardware providers' information */ |
|
1140 if (devcrypto_get_slot_info() == 0) { |
|
1141 goto failed; |
|
1142 } |
|
1143 |
|
1144 if (devcrypto_get_hw_ciphers() == 0) { |
|
1145 goto failed; |
|
1146 } |
|
1147 |
|
1148 #ifdef DEBUG |
|
1149 (void) fprintf(stderr, "cipher_count = %d\n", cipher_count); |
|
1150 for (i = 0; i < cipher_count; i++) { |
|
1151 (void) fprintf(stderr, |
|
1152 "cipher_nids[i] = %d\n", cipher_nids[i]); |
|
1153 } |
|
1154 #endif /* DEBUG */ |
|
1155 |
|
1156 if (!ENGINE_set_id(e, ENGINE_DEVCRYPTO_ID) || |
|
1157 !ENGINE_set_name(e, ENGINE_DEVCRYPTO_NAME) || |
|
1158 !ENGINE_set_ciphers(e, devcrypto_get_all_ciphers) || |
|
1159 !ENGINE_set_destroy_function(e, devcrypto_destroy) || |
|
1160 !ENGINE_set_finish_function(e, devcrypto_finish)) { |
|
1161 goto failed; |
|
1162 } |
|
1163 |
|
1164 /* Set up the devcrypto error handling */ |
|
1165 ERR_load_devcrypto_strings(); |
|
1166 return (1); |
|
1167 |
|
1168 failed: |
|
1169 devcrypto_cleanup(); |
|
1170 return (0); |
|
1171 } |
|
1172 |
|
1173 |
|
1174 static int |
|
1175 bind_helper(ENGINE *e, const char *id) |
|
1176 { |
|
1177 if (id != NULL && (strcmp(id, ENGINE_DEVCRYPTO_ID) != 0)) { |
|
1178 #ifdef DEBUG |
|
1179 (void) fprintf(stderr, "libdevcrypto - bad engine id\n"); |
|
1180 #endif /* DEBUG */ |
|
1181 return (0); |
|
1182 } |
|
1183 if (!devcrypto_bind(e)) { |
|
1184 #ifdef DEBUG |
|
1185 (void) fprintf(stderr, |
|
1186 "libdevcrypto - failed to bind engine\n"); |
|
1187 #endif /* DEBUG */ |
|
1188 return (0); |
|
1189 } |
|
1190 |
|
1191 return (1); |
|
1192 } |
|
1193 |
|
1194 IMPLEMENT_DYNAMIC_CHECK_FN() |
|
1195 IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) |
|