Print this page
fixup .text where possible
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/crypto/io/cryptoadm.c
+++ new/usr/src/uts/common/crypto/io/cryptoadm.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 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 /*
28 28 * The ioctl interface for administrative commands.
29 29 */
30 30
31 31 #include <sys/types.h>
32 32 #include <sys/modctl.h>
33 33 #include <sys/conf.h>
34 34 #include <sys/stat.h>
35 35 #include <sys/ddi.h>
36 36 #include <sys/sunddi.h>
37 37 #include <sys/kmem.h>
38 38 #include <sys/errno.h>
39 39 #include <sys/ksynch.h>
40 40 #include <sys/file.h>
41 41 #include <sys/open.h>
42 42 #include <sys/cred.h>
43 43 #include <sys/model.h>
44 44 #include <sys/sysmacros.h>
45 45 #include <sys/crypto/common.h>
46 46 #include <sys/crypto/api.h>
47 47 #include <sys/crypto/impl.h>
48 48 #include <sys/crypto/sched_impl.h>
49 49 #include <sys/crypto/ioctladmin.h>
50 50 #include <c2/audit.h>
51 51 #include <sys/disp.h>
52 52
53 53 /*
54 54 * DDI entry points.
55 55 */
56 56 static int cryptoadm_attach(dev_info_t *, ddi_attach_cmd_t);
57 57 static int cryptoadm_detach(dev_info_t *, ddi_detach_cmd_t);
58 58 static int cryptoadm_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
59 59 static int cryptoadm_open(dev_t *, int, int, cred_t *);
60 60 static int cryptoadm_close(dev_t, int, int, cred_t *);
61 61 static int cryptoadm_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
62 62
63 63 extern void audit_cryptoadm(int, char *, crypto_mech_name_t *, uint_t,
64 64 uint_t, uint32_t, int);
65 65
66 66 /*
67 67 * Module linkage.
68 68 */
69 69 static struct cb_ops cbops = {
70 70 cryptoadm_open, /* cb_open */
71 71 cryptoadm_close, /* cb_close */
72 72 nodev, /* cb_strategy */
73 73 nodev, /* cb_print */
74 74 nodev, /* cb_dump */
75 75 nodev, /* cb_read */
76 76 nodev, /* cb_write */
77 77 cryptoadm_ioctl, /* cb_ioctl */
78 78 nodev, /* cb_devmap */
79 79 nodev, /* cb_mmap */
80 80 nodev, /* cb_segmap */
81 81 nochpoll, /* cb_chpoll */
82 82 ddi_prop_op, /* cb_prop_op */
83 83 NULL, /* cb_streamtab */
84 84 D_MP, /* cb_flag */
85 85 CB_REV, /* cb_rev */
86 86 nodev, /* cb_aread */
87 87 nodev, /* cb_awrite */
88 88 };
89 89
90 90 static struct dev_ops devops = {
91 91 DEVO_REV, /* devo_rev */
92 92 0, /* devo_refcnt */
93 93 cryptoadm_getinfo, /* devo_getinfo */
94 94 nulldev, /* devo_identify */
95 95 nulldev, /* devo_probe */
96 96 cryptoadm_attach, /* devo_attach */
97 97 cryptoadm_detach, /* devo_detach */
98 98 nodev, /* devo_reset */
99 99 &cbops, /* devo_cb_ops */
100 100 NULL, /* devo_bus_ops */
101 101 NULL, /* devo_power */
102 102 ddi_quiesce_not_needed, /* devo_quiesce */
↓ open down ↓ |
102 lines elided |
↑ open up ↑ |
103 103 };
104 104
105 105 static struct modldrv modldrv = {
106 106 &mod_driverops, /* drv_modops */
107 107 "Cryptographic Administrative Interface", /* drv_linkinfo */
108 108 &devops,
109 109 };
110 110
111 111 static struct modlinkage modlinkage = {
112 112 MODREV_1, /* ml_rev */
113 - &modldrv, /* ml_linkage */
114 - NULL
113 + { &modldrv, /* ml_linkage */
114 + NULL }
115 115 };
116 116
117 117 static dev_info_t *cryptoadm_dip = NULL;
118 118
119 119 /*
120 120 * DDI entry points.
121 121 */
122 122 int
123 123 _init(void)
124 124 {
125 125 return (mod_install(&modlinkage));
126 126 }
127 127
128 128 int
129 129 _fini(void)
130 130 {
131 131 return (mod_remove(&modlinkage));
132 132 }
133 133
134 134 int
135 135 _info(struct modinfo *modinfop)
136 136 {
137 137 return (mod_info(&modlinkage, modinfop));
138 138 }
139 139
140 140 /* ARGSUSED */
141 141 static int
142 142 cryptoadm_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
143 143 {
144 144 switch (cmd) {
145 145 case DDI_INFO_DEVT2DEVINFO:
146 146 *result = (void *)cryptoadm_dip;
147 147 return (DDI_SUCCESS);
148 148
149 149 case DDI_INFO_DEVT2INSTANCE:
150 150 *result = (void *)0;
151 151 return (DDI_SUCCESS);
152 152 }
153 153 return (DDI_FAILURE);
154 154 }
155 155
156 156 static int
157 157 cryptoadm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
158 158 {
159 159 if (cmd != DDI_ATTACH) {
160 160 return (DDI_FAILURE);
161 161 }
162 162 if (ddi_get_instance(dip) != 0) {
163 163 /* we only allow instance 0 to attach */
164 164 return (DDI_FAILURE);
165 165 }
166 166
167 167 /* create the minor node */
168 168 if (ddi_create_minor_node(dip, "cryptoadm", S_IFCHR, 0,
169 169 DDI_PSEUDO, 0) != DDI_SUCCESS) {
170 170 cmn_err(CE_WARN, "cryptoadm: failed creating minor node");
171 171 ddi_remove_minor_node(dip, NULL);
172 172 return (DDI_FAILURE);
173 173 }
174 174
175 175 cryptoadm_dip = dip;
176 176
177 177 return (DDI_SUCCESS);
178 178 }
179 179
180 180 static int
181 181 cryptoadm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
182 182 {
183 183 if (cmd != DDI_DETACH)
184 184 return (DDI_FAILURE);
185 185
186 186 cryptoadm_dip = NULL;
187 187 ddi_remove_minor_node(dip, NULL);
188 188
189 189 return (DDI_SUCCESS);
190 190 }
191 191
192 192 /* ARGSUSED */
193 193 static int
194 194 cryptoadm_open(dev_t *devp, int flag, int otyp, cred_t *credp)
195 195 {
196 196 if (otyp != OTYP_CHR || cryptoadm_dip == NULL)
197 197 return (ENXIO);
198 198
199 199 /* exclusive opens are not supported */
200 200 if (flag & FEXCL)
201 201 return (ENOTSUP);
202 202
203 203 *devp = makedevice(getmajor(*devp), 0);
204 204
205 205 kcf_sched_start();
206 206
207 207 return (0);
208 208 }
209 209
210 210 /* ARGSUSED */
211 211 static int
212 212 cryptoadm_close(dev_t dev, int flag, int otyp, cred_t *credp)
213 213 {
214 214 return (0);
215 215 }
216 216
217 217 /*
218 218 * Returns TRUE if array of size MAXNAMELEN contains a '\0'
219 219 * termination character, otherwise, it returns FALSE.
220 220 */
221 221 static boolean_t
222 222 null_terminated(char *array)
223 223 {
224 224 int i;
225 225
226 226 for (i = 0; i < MAXNAMELEN; i++)
227 227 if (array[i] == '\0')
228 228 return (B_TRUE);
229 229
230 230 return (B_FALSE);
231 231 }
232 232
233 233 /*
234 234 * This ioctl returns an array of hardware providers. Each entry
235 235 * contains a device name, device instance, and number of
236 236 * supported mechanisms.
237 237 */
238 238 /* ARGSUSED */
239 239 static int
240 240 get_dev_list(dev_t dev, caddr_t arg, int mode, int *rval)
241 241 {
242 242 crypto_get_dev_list_t dev_list;
243 243 crypto_dev_list_entry_t *entries;
244 244 size_t copyout_size;
245 245 uint_t count;
246 246 ulong_t offset;
247 247
248 248 if (copyin(arg, &dev_list, sizeof (dev_list)) != 0)
249 249 return (EFAULT);
250 250
251 251 /* get the list from the core module */
252 252 if (crypto_get_dev_list(&count, &entries) != 0) {
253 253 dev_list.dl_return_value = CRYPTO_FAILED;
254 254 if (copyout(&dev_list, arg, sizeof (dev_list)) != 0) {
255 255 return (EFAULT);
256 256 }
257 257 return (0);
258 258 }
259 259
260 260 /* check if buffer is too small */
261 261 if (count > dev_list.dl_dev_count) {
262 262 dev_list.dl_dev_count = count;
263 263 dev_list.dl_return_value = CRYPTO_BUFFER_TOO_SMALL;
264 264 crypto_free_dev_list(entries, count);
265 265 if (copyout(&dev_list, arg, sizeof (dev_list)) != 0) {
266 266 return (EFAULT);
267 267 }
268 268 return (0);
269 269 }
270 270
271 271 dev_list.dl_dev_count = count;
272 272 dev_list.dl_return_value = CRYPTO_SUCCESS;
273 273
274 274 copyout_size = count * sizeof (crypto_dev_list_entry_t);
275 275
276 276 /* copyout the first stuff */
277 277 if (copyout(&dev_list, arg, sizeof (dev_list)) != 0) {
278 278 crypto_free_dev_list(entries, count);
279 279 return (EFAULT);
280 280 }
281 281
282 282 /* copyout entries */
283 283 offset = offsetof(crypto_get_dev_list_t, dl_devs);
284 284 if (count > 0 && copyout(entries, arg + offset, copyout_size) != 0) {
285 285 crypto_free_dev_list(entries, count);
286 286 return (EFAULT);
287 287 }
288 288 crypto_free_dev_list(entries, count);
289 289 return (0);
290 290 }
291 291
292 292 /*
293 293 * This ioctl returns a buffer containing the null terminated names
294 294 * of software providers.
295 295 */
296 296 /* ARGSUSED */
297 297 static int
298 298 get_soft_list(dev_t dev, caddr_t arg, int mode, int *rval)
299 299 {
300 300 STRUCT_DECL(crypto_get_soft_list, soft_list);
301 301 char *names;
302 302 size_t len;
303 303 uint_t count;
304 304
305 305 STRUCT_INIT(soft_list, mode);
306 306
307 307 if (copyin(arg, STRUCT_BUF(soft_list), STRUCT_SIZE(soft_list)) != 0)
308 308 return (EFAULT);
309 309
310 310 /* get the list from the core module */
311 311 if (crypto_get_soft_list(&count, &names, &len) != 0) {
312 312 STRUCT_FSET(soft_list, sl_return_value, CRYPTO_FAILED);
313 313 if (copyout(STRUCT_BUF(soft_list), arg,
314 314 STRUCT_SIZE(soft_list)) != 0) {
315 315 return (EFAULT);
316 316 }
317 317 return (0);
318 318 }
319 319
320 320 /* check if buffer is too small */
321 321 if (len > STRUCT_FGET(soft_list, sl_soft_len)) {
322 322 STRUCT_FSET(soft_list, sl_soft_count, count);
323 323 STRUCT_FSET(soft_list, sl_soft_len, len);
324 324 STRUCT_FSET(soft_list, sl_return_value,
325 325 CRYPTO_BUFFER_TOO_SMALL);
326 326 kmem_free(names, len);
327 327 if (copyout(STRUCT_BUF(soft_list), arg,
328 328 STRUCT_SIZE(soft_list)) != 0) {
329 329 return (EFAULT);
330 330 }
331 331 return (0);
332 332 }
333 333
334 334 STRUCT_FSET(soft_list, sl_soft_count, count);
335 335 STRUCT_FSET(soft_list, sl_soft_len, len);
336 336 STRUCT_FSET(soft_list, sl_return_value, CRYPTO_SUCCESS);
337 337
338 338 if (count > 0 && copyout(names,
339 339 STRUCT_FGETP(soft_list, sl_soft_names), len) != 0) {
340 340 kmem_free(names, len);
341 341 return (EFAULT);
342 342 }
343 343 kmem_free(names, len);
344 344
345 345 if (copyout(STRUCT_BUF(soft_list), arg, STRUCT_SIZE(soft_list)) != 0) {
346 346 return (EFAULT);
347 347 }
348 348
349 349 return (0);
350 350 }
351 351
352 352 /*
353 353 * This ioctl returns an array of mechanisms supported by the
354 354 * specified device.
355 355 */
356 356 /* ARGSUSED */
357 357 static int
358 358 get_dev_info(dev_t dev, caddr_t arg, int mode, int *rval)
359 359 {
360 360 crypto_get_dev_info_t dev_info;
361 361 crypto_mech_name_t *entries;
362 362 size_t copyout_size;
363 363 uint_t count;
364 364 ulong_t offset;
365 365 char *dev_name;
366 366 int rv;
367 367
368 368 if (copyin(arg, &dev_info, sizeof (dev_info)) != 0)
369 369 return (EFAULT);
370 370
371 371 dev_name = dev_info.di_dev_name;
372 372 /* make sure the device name is null terminated */
373 373 if (!null_terminated(dev_name)) {
374 374 dev_info.di_return_value = CRYPTO_ARGUMENTS_BAD;
375 375 if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) {
376 376 return (EFAULT);
377 377 }
378 378 return (0);
379 379 }
380 380
381 381 /* get mechanism names from the core module */
382 382 if ((rv = crypto_get_dev_info(dev_name, dev_info.di_dev_instance,
383 383 &count, &entries)) != CRYPTO_SUCCESS) {
384 384 dev_info.di_return_value = rv;
385 385 if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) {
386 386 return (EFAULT);
387 387 }
388 388 return (0);
389 389 }
390 390
391 391 /* check if buffer is too small */
392 392 if (count > dev_info.di_count) {
393 393 dev_info.di_count = count;
394 394 dev_info.di_return_value = CRYPTO_BUFFER_TOO_SMALL;
395 395 crypto_free_mech_list(entries, count);
396 396 if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) {
397 397 return (EFAULT);
398 398 }
399 399 return (0);
400 400 }
401 401
402 402 dev_info.di_count = count;
403 403 dev_info.di_return_value = CRYPTO_SUCCESS;
404 404
405 405 copyout_size = count * sizeof (crypto_mech_name_t);
406 406
407 407 /* copyout the first stuff */
408 408 if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) {
409 409 crypto_free_mech_list(entries, count);
410 410 return (EFAULT);
411 411 }
412 412
413 413 /* copyout entries */
414 414 offset = offsetof(crypto_get_dev_info_t, di_list);
415 415 if (copyout(entries, arg + offset, copyout_size) != 0) {
416 416 crypto_free_mech_list(entries, count);
417 417 return (EFAULT);
418 418 }
419 419 crypto_free_mech_list(entries, count);
420 420 return (0);
421 421 }
422 422
423 423 /*
424 424 * This ioctl returns an array of mechanisms supported by the
425 425 * specified cryptographic module.
426 426 */
427 427 /* ARGSUSED */
428 428 static int
429 429 get_soft_info(dev_t dev, caddr_t arg, int mode, int *rval)
430 430 {
431 431 crypto_get_soft_info_t soft_info;
432 432 crypto_mech_name_t *entries;
433 433 size_t copyout_size;
434 434 uint_t count;
435 435 ulong_t offset;
436 436 char *name;
437 437
438 438 if (copyin(arg, &soft_info, sizeof (soft_info)) != 0)
439 439 return (EFAULT);
440 440
441 441 name = soft_info.si_name;
442 442 /* make sure the provider name is null terminated */
443 443 if (!null_terminated(name)) {
444 444 soft_info.si_return_value = CRYPTO_ARGUMENTS_BAD;
445 445 if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) {
446 446 return (EFAULT);
447 447 }
448 448 return (0);
449 449 }
450 450
451 451 /* get mechanism names from the core module */
452 452 if (crypto_get_soft_info(name, &count, &entries) != 0) {
453 453 soft_info.si_return_value = CRYPTO_FAILED;
454 454 if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) {
455 455 return (EFAULT);
456 456 }
457 457 return (0);
458 458 }
459 459
460 460 /* check if buffer is too small */
461 461 if (count > soft_info.si_count) {
462 462 soft_info.si_count = count;
463 463 soft_info.si_return_value = CRYPTO_BUFFER_TOO_SMALL;
464 464 crypto_free_mech_list(entries, count);
465 465 if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) {
466 466 return (EFAULT);
467 467 }
468 468 return (0);
469 469 }
470 470
471 471 soft_info.si_count = count;
472 472 soft_info.si_return_value = CRYPTO_SUCCESS;
473 473 copyout_size = count * sizeof (crypto_mech_name_t);
474 474
475 475 /* copyout the first stuff */
476 476 if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) {
477 477 crypto_free_mech_list(entries, count);
478 478 return (EFAULT);
479 479 }
480 480
481 481 /* copyout entries */
482 482 offset = offsetof(crypto_get_soft_info_t, si_list);
483 483 if (copyout(entries, arg + offset, copyout_size) != 0) {
484 484 crypto_free_mech_list(entries, count);
485 485 return (EFAULT);
486 486 }
487 487 crypto_free_mech_list(entries, count);
488 488 return (0);
489 489 }
490 490
491 491 /*
492 492 * This ioctl disables mechanisms supported by the specified device.
493 493 */
494 494 /* ARGSUSED */
495 495 static int
496 496 load_dev_disabled(dev_t dev, caddr_t arg, int mode, int *rval)
497 497 {
498 498 crypto_load_dev_disabled_t dev_disabled;
499 499 crypto_mech_name_t *entries;
500 500 size_t size;
501 501 ulong_t offset;
502 502 uint_t count;
503 503 uint_t instance;
504 504 char *dev_name;
505 505 uint32_t rv;
506 506 int error = 0;
507 507
508 508 if (copyin(arg, &dev_disabled, sizeof (dev_disabled)) != 0) {
509 509 error = EFAULT;
510 510 goto out2;
511 511 }
512 512
513 513 dev_name = dev_disabled.dd_dev_name;
514 514 /* make sure the device name is null terminated */
515 515 if (!null_terminated(dev_name)) {
516 516 rv = CRYPTO_ARGUMENTS_BAD;
517 517 goto out;
518 518 }
519 519
520 520 count = dev_disabled.dd_count;
521 521 instance = dev_disabled.dd_dev_instance;
522 522 if (count == 0) {
523 523 /* remove the entry */
524 524 if (crypto_load_dev_disabled(dev_name, instance, 0, NULL) != 0)
525 525 rv = CRYPTO_FAILED;
526 526 else
527 527 rv = CRYPTO_SUCCESS;
528 528 goto out;
529 529 }
530 530
531 531 if (count > KCF_MAXMECHS) {
532 532 rv = CRYPTO_ARGUMENTS_BAD;
533 533 goto out;
534 534 }
535 535
536 536 size = count * sizeof (crypto_mech_name_t);
537 537 entries = kmem_alloc(size, KM_SLEEP);
538 538
539 539 offset = offsetof(crypto_load_dev_disabled_t, dd_list);
540 540 if (copyin(arg + offset, entries, size) != 0) {
541 541 kmem_free(entries, size);
542 542 error = EFAULT;
543 543 goto out2;
544 544 }
545 545
546 546 /* 'entries' consumed (but not freed) by crypto_load_dev_disabled() */
547 547 if (crypto_load_dev_disabled(dev_name, instance, count, entries) != 0) {
548 548 kmem_free(entries, size);
549 549 rv = CRYPTO_FAILED;
550 550 goto out;
551 551 }
552 552 rv = CRYPTO_SUCCESS;
553 553 out:
554 554 dev_disabled.dd_return_value = rv;
555 555
556 556 if (copyout(&dev_disabled, arg, sizeof (dev_disabled)) != 0) {
557 557 error = EFAULT;
558 558 }
559 559 out2:
560 560 if (AU_AUDITING())
561 561 audit_cryptoadm(CRYPTO_LOAD_DEV_DISABLED, dev_name, entries,
562 562 count, instance, rv, error);
563 563 return (error);
564 564 }
565 565
566 566 /*
567 567 * This ioctl disables mechanisms supported by the specified
568 568 * cryptographic module.
569 569 */
570 570 /* ARGSUSED */
571 571 static int
572 572 load_soft_disabled(dev_t dev, caddr_t arg, int mode, int *rval)
573 573 {
574 574 crypto_load_soft_disabled_t soft_disabled;
575 575 crypto_mech_name_t *entries;
576 576 size_t size;
577 577 uint_t count;
578 578 ulong_t offset;
579 579 char *name;
580 580 uint32_t rv;
581 581 int error = 0;
582 582
583 583 if (copyin(arg, &soft_disabled, sizeof (soft_disabled)) != 0) {
584 584 error = EFAULT;
585 585 goto out2;
586 586 }
587 587
588 588 name = soft_disabled.sd_name;
589 589 /* make sure the name is null terminated */
590 590 if (!null_terminated(name)) {
591 591 soft_disabled.sd_return_value = CRYPTO_ARGUMENTS_BAD;
592 592 if (copyout(&soft_disabled, arg, sizeof (soft_disabled)) != 0) {
593 593 return (EFAULT);
594 594 }
595 595 return (0);
596 596 }
597 597
598 598 count = soft_disabled.sd_count;
599 599 if (count == 0) {
600 600 /* remove the entry */
601 601 if (crypto_load_soft_disabled(name, 0, NULL) != 0) {
602 602 rv = CRYPTO_FAILED;
603 603 } else {
604 604 rv = CRYPTO_SUCCESS;
605 605 }
606 606 goto out;
607 607 }
608 608
609 609 if (count > KCF_MAXMECHS) {
610 610 rv = CRYPTO_ARGUMENTS_BAD;
611 611 goto out;
612 612 }
613 613
614 614 size = count * sizeof (crypto_mech_name_t);
615 615 entries = kmem_alloc(size, KM_SLEEP);
616 616
617 617 offset = offsetof(crypto_load_soft_disabled_t, sd_list);
618 618 if (copyin(arg + offset, entries, size) != 0) {
619 619 kmem_free(entries, size);
620 620 error = EFAULT;
621 621 goto out2;
622 622 }
623 623
624 624 /* 'entries' is consumed by crypto_load_soft_disabled() */
625 625 if (crypto_load_soft_disabled(name, count, entries) != 0) {
626 626 kmem_free(entries, size);
627 627 rv = CRYPTO_FAILED;
628 628 goto out;
629 629 }
630 630 rv = CRYPTO_SUCCESS;
631 631 out:
632 632 soft_disabled.sd_return_value = rv;
633 633
634 634 if (copyout(&soft_disabled, arg, sizeof (soft_disabled)) != 0) {
635 635 error = EFAULT;
636 636 }
637 637 out2:
638 638 if (AU_AUDITING())
639 639 audit_cryptoadm(CRYPTO_LOAD_SOFT_DISABLED, name, entries,
640 640 count, 0, rv, error);
641 641 return (error);
642 642 }
643 643
644 644 /*
645 645 * This ioctl loads the supported mechanisms of the specfied cryptographic
646 646 * module. This is so, at boot time, all software providers do not
647 647 * have to be opened in order to cause them to register their
648 648 * supported mechanisms.
649 649 */
650 650 /* ARGSUSED */
651 651 static int
652 652 load_soft_config(dev_t dev, caddr_t arg, int mode, int *rval)
653 653 {
654 654 crypto_load_soft_config_t soft_config;
655 655 crypto_mech_name_t *entries;
656 656 size_t size;
657 657 uint_t count;
658 658 ulong_t offset;
659 659 char *name;
660 660 uint32_t rv;
661 661 int error = 0;
662 662
663 663 if (copyin(arg, &soft_config, sizeof (soft_config)) != 0) {
664 664 error = EFAULT;
665 665 goto out2;
666 666 }
667 667
668 668 name = soft_config.sc_name;
669 669 /* make sure the name is null terminated */
670 670 if (!null_terminated(name)) {
671 671 soft_config.sc_return_value = CRYPTO_ARGUMENTS_BAD;
672 672 if (copyout(&soft_config, arg, sizeof (soft_config)) != 0) {
673 673 return (EFAULT);
674 674 }
675 675 return (0);
676 676 }
677 677
678 678 count = soft_config.sc_count;
679 679 if (count == 0) {
680 680 if (crypto_load_soft_config(name, 0, NULL) != 0) {
681 681 rv = CRYPTO_FAILED;
682 682 } else {
683 683 rv = CRYPTO_SUCCESS;
684 684 }
685 685 goto out;
686 686 }
687 687
688 688 if (count > KCF_MAXMECHS) {
689 689 rv = CRYPTO_ARGUMENTS_BAD;
690 690 goto out;
691 691 }
692 692
693 693 size = count * sizeof (crypto_mech_name_t);
694 694 entries = kmem_alloc(size, KM_SLEEP);
695 695
696 696 offset = offsetof(crypto_load_soft_config_t, sc_list);
697 697 if (copyin(arg + offset, entries, size) != 0) {
698 698 kmem_free(entries, size);
699 699 error = EFAULT;
700 700 goto out2;
701 701 }
702 702
703 703 /*
704 704 * 'entries' is consumed (but not freed) by
705 705 * crypto_load_soft_config()
706 706 */
707 707 if (crypto_load_soft_config(name, count, entries) != 0) {
708 708 kmem_free(entries, size);
709 709 rv = CRYPTO_FAILED;
710 710 goto out;
711 711 }
712 712 rv = CRYPTO_SUCCESS;
713 713 out:
714 714 soft_config.sc_return_value = rv;
715 715
716 716 if (copyout(&soft_config, arg, sizeof (soft_config)) != 0) {
717 717 error = EFAULT;
718 718 }
719 719 out2:
720 720 if (AU_AUDITING())
721 721 audit_cryptoadm(CRYPTO_LOAD_SOFT_CONFIG, name, entries, count,
722 722 0, rv, error);
723 723 return (error);
724 724 }
725 725
726 726 /*
727 727 * This ioctl unloads the specfied cryptographic module and removes
728 728 * its table of supported mechanisms.
729 729 */
730 730 /* ARGSUSED */
731 731 static int
732 732 unload_soft_module(dev_t dev, caddr_t arg, int mode, int *rval)
733 733 {
734 734 crypto_unload_soft_module_t unload_soft_module;
735 735 char *name;
736 736 uint32_t rv;
737 737 int error = 0;
738 738
739 739 if (copyin(arg, &unload_soft_module,
740 740 sizeof (unload_soft_module)) != 0) {
741 741 error = EFAULT;
742 742 goto out2;
743 743 }
744 744
745 745 name = unload_soft_module.sm_name;
746 746 /* make sure the name is null terminated */
747 747 if (!null_terminated(name)) {
748 748 unload_soft_module.sm_return_value = CRYPTO_ARGUMENTS_BAD;
749 749 if (copyout(&unload_soft_module, arg,
750 750 sizeof (unload_soft_module)) != 0) {
751 751 return (EFAULT);
752 752 }
753 753 return (0);
754 754 }
755 755
756 756 rv = crypto_unload_soft_module(name);
757 757 out:
758 758 unload_soft_module.sm_return_value = rv;
759 759
760 760 if (copyout(&unload_soft_module, arg,
761 761 sizeof (unload_soft_module)) != 0) {
762 762 error = EFAULT;
763 763 }
764 764 out2:
765 765 if (AU_AUDITING())
766 766 audit_cryptoadm(CRYPTO_UNLOAD_SOFT_MODULE, name, NULL, 0, 0,
767 767 rv, error);
768 768
769 769 return (error);
770 770 }
771 771
772 772 static int
773 773 cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
774 774 int *rval)
775 775 {
776 776 int error;
777 777 #define ARG ((caddr_t)arg)
778 778
779 779 switch (cmd) {
780 780 case CRYPTO_LOAD_DEV_DISABLED:
781 781 case CRYPTO_LOAD_SOFT_DISABLED:
782 782 case CRYPTO_LOAD_SOFT_CONFIG:
783 783 case CRYPTO_UNLOAD_SOFT_MODULE:
784 784 case CRYPTO_LOAD_DOOR:
785 785 case CRYPTO_FIPS140_SET:
786 786 if ((error = drv_priv(c)) != 0)
787 787 return (error);
788 788 default:
789 789 break;
790 790 }
791 791
792 792 switch (cmd) {
793 793 case CRYPTO_GET_DEV_LIST:
794 794 return (get_dev_list(dev, ARG, mode, rval));
795 795
796 796 case CRYPTO_GET_DEV_INFO:
797 797 return (get_dev_info(dev, ARG, mode, rval));
798 798
799 799 case CRYPTO_GET_SOFT_LIST:
800 800 return (get_soft_list(dev, ARG, mode, rval));
801 801
802 802 case CRYPTO_GET_SOFT_INFO:
803 803 return (get_soft_info(dev, ARG, mode, rval));
804 804
805 805 case CRYPTO_LOAD_DEV_DISABLED:
806 806 return (load_dev_disabled(dev, ARG, mode, rval));
807 807
808 808 case CRYPTO_LOAD_SOFT_DISABLED:
809 809 return (load_soft_disabled(dev, ARG, mode, rval));
810 810
811 811 case CRYPTO_LOAD_SOFT_CONFIG:
812 812 return (load_soft_config(dev, ARG, mode, rval));
813 813
814 814 case CRYPTO_UNLOAD_SOFT_MODULE:
815 815 return (unload_soft_module(dev, ARG, mode, rval));
816 816 }
817 817
818 818 return (EINVAL);
819 819 }
↓ open down ↓ |
695 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX