fmt: update to 11.1.3
[oi-userland.git] / components / library / openssl / openssl-0.9.8 / engines / devcrypto / e_devcrypto.c
blob2b64f82ad5db0469d1847bb12966295d83731245
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
21 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 #pragma ident "@(#)e_devcrypto.c 1.1 10/10/19 SMI"
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <pthread.h>
31 #include <errno.h>
32 #include <cryptoutil.h>
33 #include <sys/crypto/ioctl.h>
34 #include <sys/crypto/api.h>
35 #include <openssl/bio.h>
36 #include <openssl/aes.h>
37 #include <openssl/engine.h>
38 #include <security/cryptoki.h>
40 #define DEVCRYPTO_LIB_NAME "devcrypto engine"
41 #include "e_devcrypto_err.c"
43 /* DEVCRYPTO CONTEXT */
44 typedef struct devcrypto_ctx {
45 uint_t session_id;
46 } devcrypto_ctx_t;
48 /* Index for the supported ciphers */
49 typedef enum {
50 DEV_DES_CBC,
51 DEV_DES3_CBC,
52 DEV_DES_ECB,
53 DEV_DES3_ECB,
54 DEV_RC4,
55 DEV_AES_128_CBC,
56 DEV_AES_192_CBC,
57 DEV_AES_256_CBC,
58 DEV_AES_128_ECB,
59 DEV_AES_192_ECB,
60 DEV_AES_256_ECB,
61 DEV_BLOWFISH_CBC,
62 DEV_AES_128_CTR,
63 DEV_AES_192_CTR,
64 DEV_AES_256_CTR,
65 DEV_CIPHER_MAX
66 } DEV_CIPHER_ID;
68 typedef struct devcrypto_cipher {
69 DEV_CIPHER_ID id;
70 int nid;
71 int iv_len;
72 int min_key_len;
73 int max_key_len;
74 CK_KEY_TYPE key_type;
75 CK_MECHANISM_TYPE mech_type;
76 crypto_mech_type_t pn_internal_number;
77 } devcrypto_cipher_t;
80 /* Constants used when creating the ENGINE */
81 static const char *ENGINE_DEVCRYPTO_ID = "devcrypto";
82 static const char *ENGINE_DEVCRYPTO_NAME = "/dev/crypto engine support";
83 static const char *CRYPTO_DEVICE = "/dev/crypto";
85 /* static variables */
86 static int kernel_fd = -1;
87 static int kernel_fd_ref = 0;
88 static int slot_count = 0;
89 static CK_SLOT_ID *kernel_provider_id = NULL;
90 static int cipher_count = 0;
91 static int *cipher_nids = NULL;
92 pthread_mutex_t *kernel_fd_lock;
95 * NIDs for AES counter mode. They will be defined during the engine
96 * initialization.
98 static int NID_aes_128_ctr = NID_undef;
99 static int NID_aes_192_ctr = NID_undef;
100 static int NID_aes_256_ctr = NID_undef;
103 * Cipher Table for all supported symmetric ciphers.
105 static devcrypto_cipher_t cipher_table[] = {
106 { DEV_DES_CBC, NID_des_cbc, 8, 8, 8,
107 CKK_DES, CKM_DES_CBC, CRYPTO_MECH_INVALID},
108 { DEV_DES3_CBC, NID_des_ede3_cbc, 8, 24, 24,
109 CKK_DES3, CKM_DES3_CBC, CRYPTO_MECH_INVALID},
110 { DEV_DES_ECB, NID_des_ecb, 0, 8, 8,
111 CKK_DES, CKM_DES_ECB, CRYPTO_MECH_INVALID},
112 { DEV_DES3_ECB, NID_des_ede3_ecb, 0, 24, 24,
113 CKK_DES3, CKM_DES3_ECB, CRYPTO_MECH_INVALID},
114 { DEV_RC4, NID_rc4, 0, 16, 256,
115 CKK_RC4, CKM_RC4, CRYPTO_MECH_INVALID},
116 { DEV_AES_128_CBC, NID_aes_128_cbc, 16, 16, 16,
117 CKK_AES, CKM_AES_CBC, CRYPTO_MECH_INVALID},
118 { DEV_AES_192_CBC, NID_aes_192_cbc, 16, 24, 24,
119 CKK_AES, CKM_AES_CBC, CRYPTO_MECH_INVALID},
120 { DEV_AES_256_CBC, NID_aes_256_cbc, 16, 32, 32,
121 CKK_AES, CKM_AES_CBC, CRYPTO_MECH_INVALID},
122 { DEV_AES_128_ECB, NID_aes_128_ecb, 0, 16, 16,
123 CKK_AES, CKM_AES_ECB, CRYPTO_MECH_INVALID},
124 { DEV_AES_192_ECB, NID_aes_192_ecb, 0, 24, 24,
125 CKK_AES, CKM_AES_ECB, CRYPTO_MECH_INVALID},
126 { DEV_AES_256_ECB, NID_aes_256_ecb, 0, 32, 32,
127 CKK_AES, CKM_AES_ECB, CRYPTO_MECH_INVALID},
128 { DEV_BLOWFISH_CBC, NID_bf_cbc, 8, 16, 16,
129 CKK_BLOWFISH, CKM_BLOWFISH_CBC, CRYPTO_MECH_INVALID},
131 * For the following 3 AES counter mode entries, we don't know the
132 * NIDs until the engine is initialized
134 { DEV_AES_128_CTR, NID_undef, 16, 16, 16,
135 CKK_AES, CKM_AES_CTR, CRYPTO_MECH_INVALID},
136 { DEV_AES_192_CTR, NID_undef, 16, 24, 24,
137 CKK_AES, CKM_AES_CTR, CRYPTO_MECH_INVALID},
138 { DEV_AES_256_CTR, NID_undef, 16, 32, 32,
139 CKK_AES, CKM_AES_CTR, CRYPTO_MECH_INVALID},
143 /* Formal declaration for functions in EVP_CIPHER structure */
144 static int devcrypto_cipher_init(EVP_CIPHER_CTX *, const unsigned char *,
145 const unsigned char *, int);
146 static int devcrypto_cipher_do_cipher(EVP_CIPHER_CTX *, unsigned char *,
147 const unsigned char *, unsigned int);
148 static int devcrypto_cipher_cleanup(EVP_CIPHER_CTX *);
150 /* OpenSSL's libcrypto EVP stuff. This is how this engine gets wired to EVP. */
151 static const EVP_CIPHER dev_des_cbc = {
152 NID_des_cbc,
153 8, 8, 8,
154 EVP_CIPH_CBC_MODE,
155 devcrypto_cipher_init,
156 devcrypto_cipher_do_cipher,
157 devcrypto_cipher_cleanup,
158 sizeof (devcrypto_ctx_t),
159 EVP_CIPHER_set_asn1_iv,
160 EVP_CIPHER_get_asn1_iv,
161 NULL
164 static const EVP_CIPHER dev_3des_cbc = {
165 NID_des_ede3_cbc,
166 8, 24, 8,
167 EVP_CIPH_CBC_MODE,
168 devcrypto_cipher_init,
169 devcrypto_cipher_do_cipher,
170 devcrypto_cipher_cleanup,
171 sizeof (devcrypto_ctx_t),
172 EVP_CIPHER_set_asn1_iv,
173 EVP_CIPHER_get_asn1_iv,
174 NULL
178 * ECB modes don't use an Initial Vector, therefore set_asn1_parameters and
179 * get_asn1_parameters fields are set to NULL.
181 static const EVP_CIPHER dev_des_ecb = {
182 NID_des_ecb,
183 8, 8, 8,
184 EVP_CIPH_ECB_MODE,
185 devcrypto_cipher_init,
186 devcrypto_cipher_do_cipher,
187 devcrypto_cipher_cleanup,
188 sizeof (devcrypto_ctx_t),
189 NULL,
190 NULL,
191 NULL
194 static const EVP_CIPHER dev_3des_ecb = {
195 NID_des_ede3_ecb,
196 8, 24, 8,
197 EVP_CIPH_ECB_MODE,
198 devcrypto_cipher_init,
199 devcrypto_cipher_do_cipher,
200 devcrypto_cipher_cleanup,
201 sizeof (devcrypto_ctx_t),
202 NULL,
203 NULL,
204 NULL
207 static const EVP_CIPHER dev_rc4 = {
208 NID_rc4,
209 1, 16, 0,
210 EVP_CIPH_VARIABLE_LENGTH,
211 devcrypto_cipher_init,
212 devcrypto_cipher_do_cipher,
213 devcrypto_cipher_cleanup,
214 sizeof (devcrypto_ctx_t),
215 NULL,
216 NULL,
217 NULL
220 static const EVP_CIPHER dev_aes_128_cbc = {
221 NID_aes_128_cbc,
222 16, 16, 16,
223 EVP_CIPH_CBC_MODE,
224 devcrypto_cipher_init,
225 devcrypto_cipher_do_cipher,
226 devcrypto_cipher_cleanup,
227 sizeof (devcrypto_ctx_t),
228 EVP_CIPHER_set_asn1_iv,
229 EVP_CIPHER_get_asn1_iv,
230 NULL
233 static const EVP_CIPHER dev_aes_192_cbc = {
234 NID_aes_192_cbc,
235 16, 24, 16,
236 EVP_CIPH_CBC_MODE,
237 devcrypto_cipher_init,
238 devcrypto_cipher_do_cipher,
239 devcrypto_cipher_cleanup,
240 sizeof (devcrypto_ctx_t),
241 EVP_CIPHER_set_asn1_iv,
242 EVP_CIPHER_get_asn1_iv,
243 NULL
246 static const EVP_CIPHER dev_aes_256_cbc = {
247 NID_aes_256_cbc,
248 16, 32, 16,
249 EVP_CIPH_CBC_MODE,
250 devcrypto_cipher_init,
251 devcrypto_cipher_do_cipher,
252 devcrypto_cipher_cleanup,
253 sizeof (devcrypto_ctx_t),
254 EVP_CIPHER_set_asn1_iv,
255 EVP_CIPHER_get_asn1_iv,
256 NULL
261 * ECB modes don't use IV, therefore set_asn1_parameters and
262 * get_asn1_parameters are set to NULL.
264 static const EVP_CIPHER dev_aes_128_ecb = {
265 NID_aes_128_ecb,
266 16, 16, 0,
267 EVP_CIPH_ECB_MODE,
268 devcrypto_cipher_init,
269 devcrypto_cipher_do_cipher,
270 devcrypto_cipher_cleanup,
271 sizeof (devcrypto_ctx_t),
272 NULL,
273 NULL,
274 NULL
277 static const EVP_CIPHER dev_aes_192_ecb = {
278 NID_aes_192_ecb,
279 16, 24, 0,
280 EVP_CIPH_ECB_MODE,
281 devcrypto_cipher_init,
282 devcrypto_cipher_do_cipher,
283 devcrypto_cipher_cleanup,
284 sizeof (devcrypto_ctx_t),
285 NULL,
286 NULL,
287 NULL
290 static const EVP_CIPHER dev_aes_256_ecb = {
291 NID_aes_256_ecb,
292 16, 32, 0,
293 EVP_CIPH_ECB_MODE,
294 devcrypto_cipher_init,
295 devcrypto_cipher_do_cipher,
296 devcrypto_cipher_cleanup,
297 sizeof (devcrypto_ctx_t),
298 NULL,
299 NULL,
300 NULL
303 static const EVP_CIPHER dev_bf_cbc = {
304 NID_bf_cbc,
305 8, 16, 8,
306 EVP_CIPH_VARIABLE_LENGTH,
307 devcrypto_cipher_init,
308 devcrypto_cipher_do_cipher,
309 devcrypto_cipher_cleanup,
310 sizeof (devcrypto_ctx_t),
311 EVP_CIPHER_set_asn1_iv,
312 EVP_CIPHER_get_asn1_iv,
313 NULL
318 * NID_undef's will be changed for AES counter mode, as soon they are created.
320 static EVP_CIPHER dev_aes_128_ctr = {
321 NID_undef,
322 16, 16, 16,
323 EVP_CIPH_CBC_MODE,
324 devcrypto_cipher_init,
325 devcrypto_cipher_do_cipher,
326 devcrypto_cipher_cleanup,
327 sizeof (devcrypto_ctx_t),
328 EVP_CIPHER_set_asn1_iv,
329 EVP_CIPHER_get_asn1_iv,
330 NULL
333 static EVP_CIPHER dev_aes_192_ctr = {
334 NID_undef,
335 16, 24, 16,
336 EVP_CIPH_CBC_MODE,
337 devcrypto_cipher_init,
338 devcrypto_cipher_do_cipher,
339 devcrypto_cipher_cleanup,
340 sizeof (devcrypto_ctx_t),
341 EVP_CIPHER_set_asn1_iv,
342 EVP_CIPHER_get_asn1_iv,
343 NULL
346 static EVP_CIPHER dev_aes_256_ctr = {
347 NID_undef,
348 16, 32, 16,
349 EVP_CIPH_CBC_MODE,
350 devcrypto_cipher_init,
351 devcrypto_cipher_do_cipher,
352 devcrypto_cipher_cleanup,
353 sizeof (devcrypto_ctx_t),
354 EVP_CIPHER_set_asn1_iv,
355 EVP_CIPHER_get_asn1_iv,
356 NULL
362 * This function creates a new NID.
364 static int
365 devcrypto_add_NID(char *sn, char *ln)
367 ASN1_OBJECT *o;
368 int nid;
370 if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
371 1, sn, ln)) == NULL) {
372 return (0);
375 nid = OBJ_add_object(o); /* will return NID_undef on error */
376 ASN1_OBJECT_free(o);
377 return (nid);
382 * This function creates new NIDs for AES counter mode algorithms.
383 * Note that OpenSSL doesn't support them now so we have to help
384 * ourselves here.
386 static int
387 devcrypto_add_aes_ctr_NIDs(void)
389 if (NID_aes_256_ctr != NID_undef) /* already set */
390 return (1);
392 NID_aes_128_ctr = devcrypto_add_NID("AES-128-CTR", "aes-128-ctr");
393 if (NID_aes_128_ctr == NID_undef)
394 goto failed;
395 cipher_table[DEV_AES_128_CTR].nid =
396 dev_aes_128_ctr.nid = NID_aes_128_ctr;
398 NID_aes_192_ctr = devcrypto_add_NID("AES-192-CTR", "aes-192-ctr");
399 if (NID_aes_192_ctr == NID_undef)
400 goto failed;
401 cipher_table[DEV_AES_192_CTR].nid =
402 dev_aes_192_ctr.nid = NID_aes_192_ctr;
404 NID_aes_256_ctr = devcrypto_add_NID("AES-256-CTR", "aes-256-ctr");
405 if (NID_aes_256_ctr == NID_undef)
406 goto failed;
407 cipher_table[DEV_AES_256_CTR].nid =
408 dev_aes_256_ctr.nid = NID_aes_256_ctr;
410 return (1);
412 failed:
413 return (0);
417 static void
418 devcrypto_free_aes_ctr_NIDs(void)
420 ASN1_OBJECT *ob = NULL;
422 if (NID_aes_128_ctr != NID_undef) {
423 ob = OBJ_nid2obj(NID_aes_128_ctr);
424 if (ob != NULL)
425 ASN1_OBJECT_free(ob);
428 if (NID_aes_192_ctr != NID_undef) {
429 ob = OBJ_nid2obj(NID_aes_192_ctr);
430 if (ob != NULL)
431 ASN1_OBJECT_free(ob);
434 if (NID_aes_256_ctr != NID_undef) {
435 ob = OBJ_nid2obj(NID_aes_256_ctr);
436 if (ob != NULL)
437 ASN1_OBJECT_free(ob);
442 * Open the /dev/crypto device
444 static int
445 devcrypto_open()
447 int fd = -1;
449 if (kernel_fd != -1) { /* already open */
450 (void) pthread_mutex_lock(kernel_fd_lock);
451 kernel_fd_ref++;
452 (void) pthread_mutex_unlock(kernel_fd_lock);
453 return (1);
456 (void) pthread_mutex_lock(kernel_fd_lock);
457 fd = open(CRYPTO_DEVICE, O_RDWR);
458 if (fd == -1) {
459 #ifdef DEBUG
460 (void) fprintf(stderr,
461 "libdevcrypto: open /dev/crypto failed, errno=%x\n",
462 errno);
463 #endif
464 (void) pthread_mutex_unlock(kernel_fd_lock);
465 return (0);
468 if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
469 #ifdef DEBUG
470 (void) fprintf(stderr, "libdevcrypto: failed to fcntl\n");
471 #endif
472 (void) close(fd);
473 (void) pthread_mutex_unlock(kernel_fd_lock);
474 return (0);
477 kernel_fd = fd;
478 kernel_fd_ref++;
479 (void) pthread_mutex_unlock(kernel_fd_lock);
480 return (1);
485 * This function gets the total number of hardware providers presented in
486 * the system first. If there is any hardware providers, then it will get
487 * the kernel provider id for each hardware slot also.
489 static int
490 devcrypto_get_slot_info()
492 crypto_get_provider_list_t *pl = NULL;
493 int ret = 1;
494 int r;
495 int i;
497 /* Already have the information */
498 if (kernel_provider_id != NULL)
499 return (1);
501 /* Find out how many hardware slots are presented. */
502 pl = OPENSSL_malloc(sizeof (crypto_get_provider_list_t));
503 if (pl == NULL)
504 return (0);
506 pl->pl_count = 0;
507 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) {
508 if (errno != EINTR)
509 break;
511 if (r < 0 || pl->pl_return_value != CRYPTO_SUCCESS) {
512 #ifdef DEBUG
513 (void) fprintf(stderr, "libdevcrypto:CRYPTO_GET_PROVIDER_LIST:"
514 "ret (r) = 0x%x, (rv) = 0x%x\n", r, pl->pl_return_value);
515 #endif /* DEBUG */
516 ret = 0;
517 goto out;
520 slot_count = pl->pl_count;
521 if (slot_count == 0) {
522 #ifdef DEBUG
523 (void) fprintf(stderr, "libdevcrypto: no hw providers\n");
524 #endif /* DEBUG */
525 ret = 0;
526 goto out;
529 /* Get the provider ID for each slot from kernel and save it */
530 kernel_provider_id = OPENSSL_malloc(sizeof (CK_SLOT_ID) * slot_count);
531 if (kernel_provider_id == NULL) {
532 ret = 0;
533 goto out;
536 (void) OPENSSL_free(pl);
537 pl = OPENSSL_malloc(slot_count * sizeof (crypto_get_provider_list_t));
538 if (pl == NULL) {
539 ret = 0;
540 goto out;
543 pl->pl_count = slot_count;
544 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) {
545 if (errno != EINTR)
546 break;
548 if (r < 0 || (pl->pl_return_value != CRYPTO_SUCCESS)) {
549 #ifdef DEBUG
550 (void) fprintf(stderr, "libdevcrypto:CRYPTO_GET_PROVIDER_LIST:"
551 "ret (r) = 0x%x, (rv) = 0x%x\n", r, pl->pl_return_value);
552 #endif /* DEBUG */
553 ret = 0;
554 goto out;
557 for (i = 0; i < slot_count; i++) {
558 kernel_provider_id[i] = pl->pl_list[i].pe_provider_id;
559 #ifdef DEBUG
560 (void) fprintf(stderr, "libdevcrypto: i = %d, "
561 "kernel_provider_id = %d\n", i, kernel_provider_id[i]);
562 #endif /* DEBUG */
565 out:
566 if (pl != NULL)
567 (void) OPENSSL_free(pl);
569 if (ret == 0 && kernel_provider_id != NULL) {
570 (void) OPENSSL_free(kernel_provider_id);
571 kernel_provider_id = NULL;
574 return (ret);
579 * This function checks if the "nid" is already in the nid list.
581 static int
582 nid_in_list(int nid, int *nid_list, int count)
584 int i = 0;
586 if (nid_list == NULL || count <= 0)
587 return (0);
589 while (i < count) {
590 if (nid == nid_list[i])
591 break;
592 i++;
594 return (i < count ? 1 : 0);
598 * This function is to get all the ciphers supported by hardware providers.
599 * If this function is successfully completed, then the following 2 global
600 * variables will be set.
601 * cipher_count - the number of ciphers found in all hardware providers.
602 * cipher_nids - the nid list for all the ciphers.
604 static int
605 devcrypto_get_hw_ciphers(void)
607 crypto_get_provider_mechanism_info_t mechinfo;
608 int max_cipher_count;
609 int *tmp_nids = NULL;
610 const char *mech_string;
611 int r;
612 int i, j;
614 if (slot_count <= 0) /* no hardware provider */
615 return (0);
617 max_cipher_count = slot_count * DEV_CIPHER_MAX + 1;
618 tmp_nids = OPENSSL_malloc(max_cipher_count * sizeof (int));
619 if (tmp_nids == NULL) {
620 /* not enough memory */
621 goto failed;
624 for (i = 0; i < slot_count; i++) {
625 mechinfo.mi_provider_id = kernel_provider_id[i];
626 for (j = 0; j < DEV_CIPHER_MAX; j++) {
627 mech_string =
628 pkcs11_mech2str(cipher_table[j].mech_type);
629 if (mech_string == NULL) {
630 continue; /* shouldn't happen; skip it */
633 (void) strlcpy(mechinfo.mi_mechanism_name,
634 mech_string, CRYPTO_MAX_MECH_NAME);
635 while ((r = ioctl(kernel_fd,
636 CRYPTO_GET_PROVIDER_MECHANISM_INFO,
637 &mechinfo)) < 0) {
638 if (errno != EINTR)
639 break;
641 if (r < 0) {
642 goto failed;
645 if (mechinfo.mi_return_value == CRYPTO_SUCCESS) {
647 * Found this mechanism in hardware providers.
648 * If it is not in the nid list yet, add it.
650 if (!nid_in_list(cipher_table[j].nid,
651 tmp_nids, cipher_count)) {
652 tmp_nids[cipher_count] =
653 cipher_table[j].nid;
654 cipher_count++;
660 if (cipher_count > 0) {
661 cipher_nids = tmp_nids;
664 return (1);
666 failed:
667 if (r < 0 || cipher_count == 0) {
668 if (tmp_nids != NULL)
669 OPENSSL_free(tmp_nids);
671 return (0);
675 * Registered by the ENGINE when used to find out how to deal with
676 * a particular NID in the ENGINE. This says what we'll do at the
677 * top level - note, that list is restricted by what we answer with.
679 static int
680 devcrypto_get_all_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
681 const int **nids, int nid)
683 if (!cipher) {
684 *nids = (cipher_count > 0) ? cipher_nids : NULL;
685 return (cipher_count);
688 switch (nid) {
689 case NID_des_cbc:
690 *cipher = &dev_des_cbc;
691 break;
692 case NID_des_ede3_cbc:
693 *cipher = &dev_3des_cbc;
694 break;
695 case NID_des_ecb:
696 *cipher = &dev_des_ecb;
697 break;
698 case NID_des_ede3_ecb:
699 *cipher = &dev_3des_ecb;
700 break;
701 case NID_rc4:
702 *cipher = &dev_rc4;
703 break;
704 case NID_aes_128_cbc:
705 *cipher = &dev_aes_128_cbc;
706 break;
707 case NID_aes_192_cbc:
708 *cipher = &dev_aes_192_cbc;
709 break;
710 case NID_aes_256_cbc:
711 *cipher = &dev_aes_256_cbc;
712 break;
713 case NID_aes_128_ecb:
714 *cipher = &dev_aes_128_ecb;
715 break;
716 case NID_aes_192_ecb:
717 *cipher = &dev_aes_192_ecb;
718 break;
719 case NID_aes_256_ecb:
720 *cipher = &dev_aes_256_ecb;
721 break;
722 case NID_bf_cbc:
723 *cipher = &dev_bf_cbc;
724 break;
725 default:
727 * We cannot put the NIDs for AES counter mode in separated
728 * cases as above because they are not constants.
730 if (nid == NID_aes_128_ctr)
731 *cipher = &dev_aes_128_ctr;
732 else if (nid == NID_aes_192_ctr)
733 *cipher = &dev_aes_192_ctr;
734 else if (nid == NID_aes_256_ctr)
735 *cipher = &dev_aes_256_ctr;
736 else
737 *cipher = NULL;
738 break;
741 return (*cipher != NULL);
745 static int
746 get_cipher_id_by_nid(int nid)
748 int i;
750 for (i = 0; i < DEV_CIPHER_MAX; i++)
751 if (cipher_table[i].nid == nid)
752 return (cipher_table[i].id);
753 return (-1);
757 static int
758 get_slotid_by_mechanism(const char *mech_string, CK_SLOT_ID *slot_id)
760 crypto_get_provider_mechanism_info_t mechanism_info;
761 uint_t rv;
762 int r;
763 int i = 0;
765 (void) strlcpy(mechanism_info.mi_mechanism_name, mech_string,
766 CRYPTO_MAX_MECH_NAME);
767 while (i < slot_count) {
768 mechanism_info.mi_provider_id = kernel_provider_id[i];
769 while ((r = ioctl(kernel_fd,
770 CRYPTO_GET_PROVIDER_MECHANISM_INFO,
771 &mechanism_info)) < 0) {
772 if (errno != EINTR)
773 break;
775 if (r < 0) {
776 return (0); /* ioctl function failed */
778 rv = mechanism_info.mi_return_value;
779 if (rv == 0) { /* found it */
780 *slot_id = kernel_provider_id[i];
781 return (1);
783 i++;
786 return (0);
790 static int
791 devcrypto_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
792 const unsigned char *iv, int enc)
794 devcrypto_ctx_t *devc_ctx = ctx->cipher_data;
795 crypto_encrypt_init_t encrypt_init;
796 crypto_decrypt_init_t decrypt_init;
797 crypto_open_session_t session;
798 crypto_get_mechanism_number_t get_number;
799 CK_AES_CTR_PARAMS aes_ctr_params;
800 devcrypto_cipher_t *the_cipher;
801 const char *mech_string;
802 CK_SLOT_ID slot_id;
803 int index;
804 int r;
805 uint_t rv = 0;
808 if (key == NULL) {
809 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_CIPHER_KEY);
810 return (0);
813 /* get the cipher entry index in cipher_table from nid */
814 index = get_cipher_id_by_nid(ctx->cipher->nid);
815 if (index < 0 || index >= DEV_CIPHER_MAX) {
816 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_CIPHER_NID);
817 return (0);
819 the_cipher = &cipher_table[index];
821 /* check key size */
822 if (ctx->cipher->iv_len < the_cipher->iv_len ||
823 ctx->key_len < the_cipher->min_key_len ||
824 ctx->key_len > the_cipher->max_key_len) {
825 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_KEY_OR_IV_LEN_PROBLEM);
826 return (0);
829 /* get the mechanism string */
830 mech_string = pkcs11_mech2str(the_cipher->mech_type);
831 if (mech_string == NULL) {
832 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_MECH_STRING);
833 return (0);
836 #ifdef DEBUG
837 (void) fprintf(stderr, "libdevcrypto: mech_string=%s\n", mech_string);
838 #endif
840 /* Find the slot that supports this mechanism */
841 if (!get_slotid_by_mechanism(mech_string, &slot_id)) {
842 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_FIND_SLOT_BY_MECH);
843 #ifdef DEBUG
844 (void) fprintf(stderr,
845 "libdevcrypto: failed to find a slot with %s\n",
846 mech_string);
847 #endif
848 return (0);
851 #ifdef DEBUG
852 (void) fprintf(stderr, "libdevcrypto: found a slot with %s, "
853 "slot_id = %d\n", mech_string, slot_id);
854 #endif
856 /* Open a session on this slot */
857 session.os_provider_id = slot_id;
858 session.os_flags = CKF_RW_SESSION | CKF_SERIAL_SESSION;
859 while ((r = ioctl(kernel_fd, CRYPTO_OPEN_SESSION, &session)) < 0) {
860 if (errno != EINTR)
861 break;
863 rv = session.os_return_value;
864 if (r || rv) {
865 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_OPEN_SESSION);
866 #ifdef DEBUG
867 (void) fprintf(stderr,
868 "libdevcrypto:cipher_init:failed to open a session\n");
869 #endif /* DEBUG */
870 goto failed;
873 #ifdef DEBUG
874 (void) fprintf(stderr, "libdevcrypto:cipher_init: open session = %d\n",
875 session.os_session);
876 #endif /* DEBUG */
878 /* save the session_id */
879 devc_ctx->session_id = session.os_session;
882 * Get the kernel mechanism number for this mechanism, if it has not
883 * been retrieved yet.
885 if (the_cipher->pn_internal_number == CRYPTO_MECH_INVALID) {
886 get_number.pn_mechanism_string = (char *)mech_string;
887 get_number.pn_mechanism_len = strlen(mech_string) + 1;
888 while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER,
889 &get_number)) < 0) {
890 if (errno != EINTR)
891 break;
893 rv = get_number.pn_return_value;
894 if (r || rv) {
895 DEVCRYPTOerr(DEVC_F_CIPHER_INIT,
896 DEVC_R_GET_MECHANISM_NUMBER);
897 #ifdef DEBUG
898 (void) fprintf(stderr, "libdevcrypto:cipher_init: "
899 "failed to get the kernel mech number.\n");
900 #endif /* DEBUG */
901 goto failed;
904 the_cipher->pn_internal_number = get_number.pn_internal_number;
907 /* Crypto Init */
908 if (ctx->encrypt) {
909 encrypt_init.ei_session = session.os_session;
910 encrypt_init.ei_key.ck_format = CRYPTO_KEY_RAW;
911 encrypt_init.ei_key.ck_obj_id = 0;
912 encrypt_init.ei_key.ck_data = (void *) key;
913 encrypt_init.ei_key.ck_length = ctx->key_len * 8;
914 encrypt_init.ei_mech.cm_type = the_cipher->pn_internal_number;
916 if (ctx->cipher->nid == NID_aes_128_ctr ||
917 ctx->cipher->nid == NID_aes_192_ctr ||
918 ctx->cipher->nid == NID_aes_256_ctr) {
919 encrypt_init.ei_mech.cm_param =
920 (void *) (&aes_ctr_params);
921 encrypt_init.ei_mech.cm_param_len =
922 sizeof (aes_ctr_params);
924 aes_ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
925 OPENSSL_assert(ctx->cipher->iv_len == AES_BLOCK_SIZE);
926 (void) memcpy(aes_ctr_params.cb, ctx->iv,
927 AES_BLOCK_SIZE);
928 } else {
929 if (the_cipher->iv_len > 0) {
930 encrypt_init.ei_mech.cm_param =
931 (char *)ctx->iv;
932 encrypt_init.ei_mech.cm_param_len =
933 ctx->cipher->iv_len;
934 } else {
935 encrypt_init.ei_mech.cm_param = NULL;
936 encrypt_init.ei_mech.cm_param_len = 0;
940 while ((r = ioctl(kernel_fd, CRYPTO_ENCRYPT_INIT,
941 &encrypt_init)) < 0) {
942 if (errno != EINTR)
943 break;
945 rv = encrypt_init.ei_return_value;
947 } else {
948 decrypt_init.di_session = session.os_session;
949 decrypt_init.di_key.ck_format = CRYPTO_KEY_RAW;
950 decrypt_init.di_key.ck_obj_id = 0;
951 decrypt_init.di_key.ck_data = (void *) key;
952 decrypt_init.di_key.ck_length = ctx->key_len * 8;
953 decrypt_init.di_mech.cm_type = the_cipher->pn_internal_number;
955 if (ctx->cipher->nid == NID_aes_128_ctr ||
956 ctx->cipher->nid == NID_aes_192_ctr ||
957 ctx->cipher->nid == NID_aes_256_ctr) {
958 decrypt_init.di_mech.cm_param =
959 (void *)(&aes_ctr_params);
960 decrypt_init.di_mech.cm_param_len =
961 sizeof (aes_ctr_params);
962 aes_ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
963 OPENSSL_assert(ctx->cipher->iv_len == AES_BLOCK_SIZE);
964 (void) memcpy(aes_ctr_params.cb, ctx->iv,
965 AES_BLOCK_SIZE);
966 } else {
967 if (the_cipher->iv_len > 0) {
968 decrypt_init.di_mech.cm_param =
969 (char *)ctx->iv;
970 decrypt_init.di_mech.cm_param_len =
971 ctx->cipher->iv_len;
972 } else {
973 decrypt_init.di_mech.cm_param = NULL;
974 decrypt_init.di_mech.cm_param_len = 0;
978 while ((r = ioctl(kernel_fd, CRYPTO_DECRYPT_INIT,
979 &decrypt_init)) < 0) {
980 if (errno != EINTR)
981 break;
983 rv = decrypt_init.di_return_value;
986 failed:
987 if (r || rv) {
988 if (ctx->encrypt)
989 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_ENCRYPT_INIT);
990 else
991 DEVCRYPTOerr(DEVC_F_CIPHER_INIT, DEVC_R_DECRYPT_INIT);
993 return (0);
996 return (1);
1001 * ENCRYPT_UPDATE or DECRYPT_UPDATE
1003 static int
1004 devcrypto_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1005 const unsigned char *in, unsigned int inl)
1007 crypto_encrypt_update_t encrypt_update;
1008 crypto_decrypt_update_t decrypt_update;
1009 devcrypto_ctx_t *devc_ctx = ctx->cipher_data;
1010 int r = 0, rv = 0;
1012 if (ctx->encrypt) {
1013 encrypt_update.eu_session = devc_ctx->session_id;
1014 encrypt_update.eu_databuf = (char *)in;
1015 encrypt_update.eu_datalen = inl;
1016 encrypt_update.eu_encrbuf = (char *)out;
1017 encrypt_update.eu_encrlen = inl;
1019 while ((r = ioctl(kernel_fd, CRYPTO_ENCRYPT_UPDATE,
1020 &encrypt_update)) < 0) {
1021 if (errno != EINTR)
1022 break;
1024 rv = encrypt_update.eu_return_value;
1026 } else { /* decrypt */
1027 decrypt_update.du_session = devc_ctx->session_id;
1028 decrypt_update.du_encrbuf = (char *)in;
1029 decrypt_update.du_encrlen = inl;
1030 decrypt_update.du_databuf = (char *)out;
1031 decrypt_update.du_datalen = inl;
1033 while ((r = ioctl(kernel_fd, CRYPTO_DECRYPT_UPDATE,
1034 &decrypt_update)) < 0) {
1035 if (errno != EINTR)
1036 break;
1038 rv = decrypt_update.du_return_value;
1041 if (r || rv) {
1042 if (ctx->encrypt)
1043 DEVCRYPTOerr(DEVC_F_CIPHER_DO_CIPHER,
1044 DEVC_R_ENCRYPT_UPDATE);
1045 else
1046 DEVCRYPTOerr(DEVC_F_CIPHER_DO_CIPHER,
1047 DEVC_R_DECRYPT_UPDATE);
1049 #ifdef DEBUG
1050 (void) fprintf(stderr, "libdevcrypto:crypto_do ret (r) = 0x%x,"
1051 "crypto ret (rv) = 0x%x,", r, rv);
1052 #endif /* DEBUG */
1053 return (0);
1056 return (1);
1061 * ENCRYPT_FINAL or DECRYPT_FINAL
1063 static int
1064 devcrypto_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1066 crypto_encrypt_final_t encrypt_final;
1067 crypto_decrypt_final_t decrypt_final;
1068 crypto_close_session_t session;
1069 devcrypto_ctx_t *devc_ctx = ctx->cipher_data;
1070 char buf[EVP_MAX_BLOCK_LENGTH];
1071 int r;
1072 uint_t rv = 0;
1073 int ret = 1;
1075 if (ctx->encrypt) {
1076 encrypt_final.ef_session = devc_ctx->session_id;
1077 encrypt_final.ef_encrbuf = buf;
1078 encrypt_final.ef_encrlen = sizeof (buf);
1079 while ((r = ioctl(kernel_fd, CRYPTO_ENCRYPT_FINAL,
1080 &encrypt_final)) < 0) {
1081 if (errno != EINTR)
1082 break;
1084 rv = encrypt_final.ef_return_value;
1086 } else {
1087 decrypt_final.df_session = devc_ctx->session_id;
1088 decrypt_final.df_databuf = buf;
1089 decrypt_final.df_datalen = sizeof (buf);
1090 while ((r = ioctl(kernel_fd, CRYPTO_DECRYPT_FINAL,
1091 &decrypt_final)) < 0) {
1092 if (errno != EINTR)
1093 break;
1095 rv = decrypt_final.df_return_value;
1098 #ifdef DEBUG
1099 if (ctx->encrypt)
1100 (void) fprintf(stderr, "libdevcrypto:CRYPTO_ENCRYPT_FINAL "
1101 "ret (r) = 0x%x, (rv) = 0x%x\n", r, rv);
1102 else
1103 (void) fprintf(stderr, "libdevcrypto:CRYPTO_DECRYPT_FINAL "
1104 "ret (r) = 0x%x, (rv) = 0x%x\n", r, rv);
1105 #endif /* DEBUG */
1107 if (r || rv) {
1108 if (ctx->encrypt)
1109 DEVCRYPTOerr(DEVC_F_CIPHER_CLEANUP,
1110 DEVC_R_ENCRYPT_FINAL);
1111 else
1112 DEVCRYPTOerr(DEVC_F_CIPHER_CLEANUP,
1113 DEVC_R_DECRYPT_FINAL);
1114 ret = 0;
1117 /* close the session */
1118 session.cs_session = devc_ctx->session_id;
1119 while ((r = ioctl(kernel_fd, CRYPTO_CLOSE_SESSION, &session)) < 0) {
1120 if (errno != EINTR)
1121 break;
1124 #ifdef DEBUG
1125 (void) fprintf(stderr, "libdevcrypto:CRYPTO_CLOSE_SESSION, "
1126 "session id = %d ret (r) = 0x%x, crypto ret (rv) = 0x%x\n",
1127 devc_ctx->session_id, r, rv);
1128 #endif /* DEBUG */
1130 if (r || rv) {
1131 DEVCRYPTOerr(DEVC_F_CIPHER_CLEANUP, DEVC_R_CLOSE_SESSION);
1132 ret = 0;
1135 return (ret);
1138 static void
1139 devcrypto_cleanup()
1141 if (kernel_fd == -1)
1142 return;
1144 (void) pthread_mutex_lock(kernel_fd_lock);
1145 kernel_fd_ref--;
1146 (void) pthread_mutex_unlock(kernel_fd_lock);
1148 if (kernel_fd_ref == 0) {
1149 (void) pthread_mutex_lock(kernel_fd_lock);
1150 (void) close(kernel_fd);
1151 kernel_fd = -1;
1152 if (kernel_provider_id != NULL) {
1153 OPENSSL_free(kernel_provider_id);
1154 kernel_provider_id = NULL;
1156 if (cipher_nids != NULL) {
1157 OPENSSL_free(cipher_nids);
1158 cipher_nids = NULL;
1160 devcrypto_free_aes_ctr_NIDs();
1161 (void) pthread_mutex_unlock(kernel_fd_lock);
1162 (void) pthread_mutex_destroy(kernel_fd_lock);
1163 OPENSSL_free(kernel_fd_lock);
1164 kernel_fd_lock = NULL;
1168 static int
1169 devcrypto_destroy(ENGINE *e)
1171 ERR_unload_devcrypto_strings();
1172 return (1);
1175 static int
1176 devcrypto_finish(ENGINE *e)
1178 devcrypto_cleanup();
1179 return (1);
1183 * Set up the engine info and get the /dev/crypto engine ready.
1185 static int
1186 devcrypto_bind(ENGINE *e)
1188 #ifdef DEBUG
1189 int i;
1190 #endif
1192 /* Get the NIDs for AES counter mode algorithms first. */
1193 if (devcrypto_add_aes_ctr_NIDs() == 0) {
1194 return (0);
1197 /* Create a lock for the devcrypto device file descriptor */
1198 if (kernel_fd_lock == NULL) {
1199 kernel_fd_lock = OPENSSL_malloc(sizeof (pthread_mutex_t));
1200 if (kernel_fd_lock == NULL) {
1201 devcrypto_free_aes_ctr_NIDs();
1202 return (0);
1205 if (pthread_mutex_init(kernel_fd_lock, NULL) != 0) {
1206 devcrypto_free_aes_ctr_NIDs();
1207 OPENSSL_free(kernel_fd_lock);
1208 kernel_fd_lock = NULL;
1209 return (0);
1213 /* Open the /dev/crypto device */
1214 if (devcrypto_open() == 0) {
1215 devcrypto_free_aes_ctr_NIDs();
1216 pthread_mutex_destroy(kernel_fd_lock);
1217 OPENSSL_free(kernel_fd_lock);
1218 kernel_fd_lock = NULL;
1219 return (0);
1222 /* Get all hardware providers' information */
1223 if (devcrypto_get_slot_info() == 0) {
1224 goto failed;
1227 if (devcrypto_get_hw_ciphers() == 0) {
1228 goto failed;
1231 #ifdef DEBUG
1232 (void) fprintf(stderr, "cipher_count = %d\n", cipher_count);
1233 for (i = 0; i < cipher_count; i++) {
1234 (void) fprintf(stderr,
1235 "cipher_nids[i] = %d\n", cipher_nids[i]);
1237 #endif /* DEBUG */
1239 if (!ENGINE_set_id(e, ENGINE_DEVCRYPTO_ID) ||
1240 !ENGINE_set_name(e, ENGINE_DEVCRYPTO_NAME) ||
1241 !ENGINE_set_ciphers(e, devcrypto_get_all_ciphers) ||
1242 !ENGINE_set_destroy_function(e, devcrypto_destroy) ||
1243 !ENGINE_set_finish_function(e, devcrypto_finish)) {
1244 goto failed;
1247 /* Set up the devcrypto error handling */
1248 ERR_load_devcrypto_strings();
1249 return (1);
1251 failed:
1252 devcrypto_cleanup();
1253 return (0);
1257 static int
1258 bind_helper(ENGINE *e, const char *id)
1260 if (id != NULL && (strcmp(id, ENGINE_DEVCRYPTO_ID) != 0)) {
1261 #ifdef DEBUG
1262 (void) fprintf(stderr, "libdevcrypto - bad engine id\n");
1263 #endif /* DEBUG */
1264 return (0);
1266 if (!devcrypto_bind(e)) {
1267 #ifdef DEBUG
1268 (void) fprintf(stderr,
1269 "libdevcrypto - failed to bind engine\n");
1270 #endif /* DEBUG */
1271 return (0);
1274 return (1);
1277 IMPLEMENT_DYNAMIC_CHECK_FN()
1278 IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)