1 /* $NetBSD: crypto.c,v 1.14 2006/06/07 22:34:18 kardel Exp $ */ 2 /* $FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.5 2003/02/26 00:14:05 sam Exp $ */ 3 /* $OpenBSD: crypto.c,v 1.41 2002/07/17 23:52:38 art Exp $ */ 4 5 /* 6 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) 7 * 8 * This code was written by Angelos D. Keromytis in Athens, Greece, in 9 * February 2000. Network Security Technologies Inc. (NSTI) kindly 10 * supported the development of this code. 11 * 12 * Copyright (c) 2000, 2001 Angelos D. Keromytis 13 * 14 * Permission to use, copy, and modify this software with or without fee 15 * is hereby granted, provided that this entire notice is included in 16 * all source code copies of any software which is or includes a copy or 17 * modification of this software. 18 * 19 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 20 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 21 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 22 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 23 * PURPOSE. 24 */ 25 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.14 2006/06/07 22:34:18 kardel Exp $"); 28 29 /* XXX FIXME: should be defopt'ed */ 30 #define CRYPTO_TIMING /* enable cryptop timing stuff */ 31 32 #include <sys/param.h> 33 #include <sys/reboot.h> 34 #include <sys/systm.h> 35 #include <sys/malloc.h> 36 #include <sys/proc.h> 37 #include <sys/pool.h> 38 #include <opencrypto/cryptodev.h> 39 #include <sys/kthread.h> 40 #include <sys/once.h> 41 #include <sys/sysctl.h> 42 43 #include <opencrypto/xform.h> /* XXX for M_XDATA */ 44 45 #ifdef __NetBSD__ 46 #define splcrypto splnet 47 /* below is kludges to check whats still missing */ 48 #define SWI_CRYPTO 17 49 #define register_swi(lvl, fn) \ 50 softintr_establish(IPL_SOFTNET, (void (*)(void*))fn, NULL) 51 #define unregister_swi(lvl, fn) softintr_disestablish(softintr_cookie) 52 #define setsoftcrypto(x) softintr_schedule(x) 53 #endif 54 55 #define SESID2HID(sid) (((sid) >> 32) & 0xffffffff) 56 57 /* 58 * Crypto drivers register themselves by allocating a slot in the 59 * crypto_drivers table with crypto_get_driverid() and then registering 60 * each algorithm they support with crypto_register() and crypto_kregister(). 61 */ 62 static struct cryptocap *crypto_drivers; 63 static int crypto_drivers_num; 64 static void* softintr_cookie; 65 66 /* 67 * There are two queues for crypto requests; one for symmetric (e.g. 68 * cipher) operations and one for asymmetric (e.g. MOD) operations. 69 * See below for how synchronization is handled. 70 */ 71 static TAILQ_HEAD(,cryptop) crp_q = /* request queues */ 72 TAILQ_HEAD_INITIALIZER(crp_q); 73 static TAILQ_HEAD(,cryptkop) crp_kq = 74 TAILQ_HEAD_INITIALIZER(crp_kq); 75 76 /* 77 * There are two queues for processing completed crypto requests; one 78 * for the symmetric and one for the asymmetric ops. We only need one 79 * but have two to avoid type futzing (cryptop vs. cryptkop). See below 80 * for how synchronization is handled. 81 */ 82 static TAILQ_HEAD(,cryptop) crp_ret_q = /* callback queues */ 83 TAILQ_HEAD_INITIALIZER(crp_ret_q); 84 static TAILQ_HEAD(,cryptkop) crp_ret_kq = 85 TAILQ_HEAD_INITIALIZER(crp_ret_kq); 86 87 /* 88 * Crypto op and desciptor data structures are allocated 89 * from separate private zones(FreeBSD)/pools(netBSD/OpenBSD) . 90 */ 91 struct pool cryptop_pool; 92 struct pool cryptodesc_pool; 93 int crypto_pool_initialized = 0; 94 95 #ifdef __NetBSD__ 96 static void deferred_crypto_thread(void *arg); 97 #endif 98 99 int crypto_usercrypto = 1; /* userland may open /dev/crypto */ 100 int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */ 101 /* 102 * cryptodevallowsoft is (intended to be) sysctl'able, controlling 103 * access to hardware versus software transforms as below: 104 * 105 * crypto_devallowsoft < 0: Force userlevel requests to use software 106 * transforms, always 107 * crypto_devallowsoft = 0: Use hardware if present, grant userlevel 108 * requests for non-accelerated transforms 109 * (handling the latter in software) 110 * crypto_devallowsoft > 0: Allow user requests only for transforms which 111 * are hardware-accelerated. 112 */ 113 int crypto_devallowsoft = 1; /* only use hardware crypto */ 114 115 #ifdef __FreeBSD__ 116 SYSCTL_INT(_kern, OID_AUTO, usercrypto, CTLFLAG_RW, 117 &crypto_usercrypto, 0, 118 "Enable/disable user-mode access to crypto support"); 119 SYSCTL_INT(_kern, OID_AUTO, userasymcrypto, CTLFLAG_RW, 120 &crypto_userasymcrypto, 0, 121 "Enable/disable user-mode access to asymmetric crypto support"); 122 SYSCTL_INT(_kern, OID_AUTO, cryptodevallowsoft, CTLFLAG_RW, 123 &crypto_devallowsoft, 0, 124 "Enable/disable use of software asym crypto support"); 125 #endif 126 #ifdef __NetBSD__ 127 SYSCTL_SETUP(sysctl_opencrypto_setup, "sysctl opencrypto subtree setup") 128 { 129 sysctl_createv(clog, 0, NULL, NULL, 130 CTLFLAG_PERMANENT, 131 CTLTYPE_NODE, "kern", NULL, 132 NULL, 0, NULL, 0, 133 CTL_KERN, CTL_EOL); 134 sysctl_createv(clog, 0, NULL, NULL, 135 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 136 CTLTYPE_INT, "usercrypto", 137 SYSCTL_DESCR("Enable/disable user-mode access to " 138 "crypto support"), 139 NULL, 0, &crypto_usercrypto, 0, 140 CTL_KERN, CTL_CREATE, CTL_EOL); 141 sysctl_createv(clog, 0, NULL, NULL, 142 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 143 CTLTYPE_INT, "userasymcrypto", 144 SYSCTL_DESCR("Enable/disable user-mode access to " 145 "asymmetric crypto support"), 146 NULL, 0, &crypto_userasymcrypto, 0, 147 CTL_KERN, CTL_CREATE, CTL_EOL); 148 sysctl_createv(clog, 0, NULL, NULL, 149 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 150 CTLTYPE_INT, "cryptodevallowsoft", 151 SYSCTL_DESCR("Enable/disable use of software " 152 "asymmetric crypto support"), 153 NULL, 0, &crypto_devallowsoft, 0, 154 CTL_KERN, CTL_CREATE, CTL_EOL); 155 } 156 #endif 157 158 MALLOC_DEFINE(M_CRYPTO_DATA, "crypto", "crypto session records"); 159 160 /* 161 * Synchronization: read carefully, this is non-trivial. 162 * 163 * Crypto requests are submitted via crypto_dispatch. Typically 164 * these come in from network protocols at spl0 (output path) or 165 * spl[,soft]net (input path). 166 * 167 * Requests are typically passed on the driver directly, but they 168 * may also be queued for processing by a software interrupt thread, 169 * cryptointr, that runs at splsoftcrypto. This thread dispatches 170 * the requests to crypto drivers (h/w or s/w) who call crypto_done 171 * when a request is complete. Hardware crypto drivers are assumed 172 * to register their IRQ's as network devices so their interrupt handlers 173 * and subsequent "done callbacks" happen at spl[imp,net]. 174 * 175 * Completed crypto ops are queued for a separate kernel thread that 176 * handles the callbacks at spl0. This decoupling insures the crypto 177 * driver interrupt service routine is not delayed while the callback 178 * takes place and that callbacks are delivered after a context switch 179 * (as opposed to a software interrupt that clients must block). 180 * 181 * This scheme is not intended for SMP machines. 182 */ 183 static void cryptointr(void); /* swi thread to dispatch ops */ 184 static void cryptoret(void); /* kernel thread for callbacks*/ 185 static struct proc *cryptoproc; 186 static void crypto_destroy(void); 187 static int crypto_invoke(struct cryptop *crp, int hint); 188 static int crypto_kinvoke(struct cryptkop *krp, int hint); 189 190 static struct cryptostats cryptostats; 191 static int crypto_timing = 0; 192 193 #ifdef __FreeBSD__ 194 SYSCTL_STRUCT(_kern, OID_AUTO, crypto_stats, CTLFLAG_RW, &cryptostats, 195 cryptostats, "Crypto system statistics"); 196 197 SYSCTL_INT(_debug, OID_AUTO, crypto_timing, CTLFLAG_RW, 198 &crypto_timing, 0, "Enable/disable crypto timing support"); 199 SYSCTL_STRUCT(_kern, OID_AUTO, crypto_stats, CTLFLAG_RW, &cryptostats, 200 cryptostats, "Crypto system statistics"); 201 #endif /* __FreeBSD__ */ 202 203 static int 204 crypto_init0(void) 205 { 206 #ifdef __FreeBSD__ 207 int error; 208 209 cryptop_zone = zinit("cryptop", sizeof (struct cryptop), 0, 0, 1); 210 cryptodesc_zone = zinit("cryptodesc", sizeof (struct cryptodesc), 211 0, 0, 1); 212 if (cryptodesc_zone == NULL || cryptop_zone == NULL) { 213 printf("crypto_init: cannot setup crypto zones\n"); 214 return; 215 } 216 #endif 217 218 crypto_drivers = malloc(CRYPTO_DRIVERS_INITIAL * 219 sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT | M_ZERO); 220 if (crypto_drivers == NULL) { 221 printf("crypto_init: cannot malloc driver table\n"); 222 return 0; 223 } 224 crypto_drivers_num = CRYPTO_DRIVERS_INITIAL; 225 226 softintr_cookie = register_swi(SWI_CRYPTO, cryptointr); 227 #ifdef __FreeBSD__ 228 error = kthread_create((void (*)(void *)) cryptoret, NULL, 229 &cryptoproc, "cryptoret"); 230 if (error) { 231 printf("crypto_init: cannot start cryptoret thread; error %d", 232 error); 233 crypto_destroy(); 234 } 235 #else 236 /* defer thread creation until after boot */ 237 kthread_create( deferred_crypto_thread, NULL); 238 #endif 239 return 0; 240 } 241 242 void 243 crypto_init(void) 244 { 245 ONCE_DECL(crypto_init_once); 246 247 RUN_ONCE(&crypto_init_once, crypto_init0); 248 } 249 250 static void 251 crypto_destroy(void) 252 { 253 /* XXX no wait to reclaim zones */ 254 if (crypto_drivers != NULL) 255 free(crypto_drivers, M_CRYPTO_DATA); 256 unregister_swi(SWI_CRYPTO, cryptointr); 257 } 258 259 /* 260 * Create a new session. 261 */ 262 int 263 crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard) 264 { 265 struct cryptoini *cr; 266 u_int32_t hid, lid; 267 int err = EINVAL; 268 int s; 269 270 s = splcrypto(); 271 272 if (crypto_drivers == NULL) 273 goto done; 274 275 /* 276 * The algorithm we use here is pretty stupid; just use the 277 * first driver that supports all the algorithms we need. 278 * 279 * XXX We need more smarts here (in real life too, but that's 280 * XXX another story altogether). 281 */ 282 283 for (hid = 0; hid < crypto_drivers_num; hid++) { 284 /* 285 * If it's not initialized or has remaining sessions 286 * referencing it, skip. 287 */ 288 if (crypto_drivers[hid].cc_newsession == NULL || 289 (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP)) 290 continue; 291 292 /* Hardware required -- ignore software drivers. */ 293 if (hard > 0 && 294 (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE)) 295 continue; 296 /* Software required -- ignore hardware drivers. */ 297 if (hard < 0 && 298 (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) == 0) 299 continue; 300 301 /* See if all the algorithms are supported. */ 302 for (cr = cri; cr; cr = cr->cri_next) 303 if (crypto_drivers[hid].cc_alg[cr->cri_alg] == 0) 304 break; 305 306 if (cr == NULL) { 307 /* Ok, all algorithms are supported. */ 308 309 /* 310 * Can't do everything in one session. 311 * 312 * XXX Fix this. We need to inject a "virtual" session layer right 313 * XXX about here. 314 */ 315 316 /* Call the driver initialization routine. */ 317 lid = hid; /* Pass the driver ID. */ 318 err = crypto_drivers[hid].cc_newsession( 319 crypto_drivers[hid].cc_arg, &lid, cri); 320 if (err == 0) { 321 (*sid) = hid; 322 (*sid) <<= 32; 323 (*sid) |= (lid & 0xffffffff); 324 crypto_drivers[hid].cc_sessions++; 325 } 326 goto done; 327 /*break;*/ 328 } 329 } 330 done: 331 splx(s); 332 return err; 333 } 334 335 /* 336 * Delete an existing session (or a reserved session on an unregistered 337 * driver). 338 */ 339 int 340 crypto_freesession(u_int64_t sid) 341 { 342 u_int32_t hid; 343 int err = 0; 344 int s; 345 346 s = splcrypto(); 347 348 if (crypto_drivers == NULL) { 349 err = EINVAL; 350 goto done; 351 } 352 353 /* Determine two IDs. */ 354 hid = SESID2HID(sid); 355 356 if (hid >= crypto_drivers_num) { 357 err = ENOENT; 358 goto done; 359 } 360 361 if (crypto_drivers[hid].cc_sessions) 362 crypto_drivers[hid].cc_sessions--; 363 364 /* Call the driver cleanup routine, if available. */ 365 if (crypto_drivers[hid].cc_freesession) 366 err = crypto_drivers[hid].cc_freesession( 367 crypto_drivers[hid].cc_arg, sid); 368 else 369 err = 0; 370 371 /* 372 * If this was the last session of a driver marked as invalid, 373 * make the entry available for reuse. 374 */ 375 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) && 376 crypto_drivers[hid].cc_sessions == 0) 377 bzero(&crypto_drivers[hid], sizeof(struct cryptocap)); 378 379 done: 380 splx(s); 381 return err; 382 } 383 384 /* 385 * Return an unused driver id. Used by drivers prior to registering 386 * support for the algorithms they handle. 387 */ 388 int32_t 389 crypto_get_driverid(u_int32_t flags) 390 { 391 struct cryptocap *newdrv; 392 int i, s; 393 394 crypto_init(); 395 396 s = splcrypto(); 397 for (i = 0; i < crypto_drivers_num; i++) 398 if (crypto_drivers[i].cc_process == NULL && 399 (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0 && 400 crypto_drivers[i].cc_sessions == 0) 401 break; 402 403 /* Out of entries, allocate some more. */ 404 if (i == crypto_drivers_num) { 405 /* Be careful about wrap-around. */ 406 if (2 * crypto_drivers_num <= crypto_drivers_num) { 407 splx(s); 408 printf("crypto: driver count wraparound!\n"); 409 return -1; 410 } 411 412 newdrv = malloc(2 * crypto_drivers_num * 413 sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 414 if (newdrv == NULL) { 415 splx(s); 416 printf("crypto: no space to expand driver table!\n"); 417 return -1; 418 } 419 420 bcopy(crypto_drivers, newdrv, 421 crypto_drivers_num * sizeof(struct cryptocap)); 422 423 crypto_drivers_num *= 2; 424 425 free(crypto_drivers, M_CRYPTO_DATA); 426 crypto_drivers = newdrv; 427 } 428 429 /* NB: state is zero'd on free */ 430 crypto_drivers[i].cc_sessions = 1; /* Mark */ 431 crypto_drivers[i].cc_flags = flags; 432 433 if (bootverbose) 434 printf("crypto: assign driver %u, flags %u\n", i, flags); 435 436 splx(s); 437 438 return i; 439 } 440 441 static struct cryptocap * 442 crypto_checkdriver(u_int32_t hid) 443 { 444 if (crypto_drivers == NULL) 445 return NULL; 446 return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]); 447 } 448 449 /* 450 * Register support for a key-related algorithm. This routine 451 * is called once for each algorithm supported a driver. 452 */ 453 int 454 crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags, 455 int (*kprocess)(void*, struct cryptkop *, int), 456 void *karg) 457 { 458 int s; 459 struct cryptocap *cap; 460 int err; 461 462 s = splcrypto(); 463 464 cap = crypto_checkdriver(driverid); 465 if (cap != NULL && 466 (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) { 467 /* 468 * XXX Do some performance testing to determine placing. 469 * XXX We probably need an auxiliary data structure that 470 * XXX describes relative performances. 471 */ 472 473 cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED; 474 if (bootverbose) 475 printf("crypto: driver %u registers key alg %u flags %u\n" 476 , driverid 477 , kalg 478 , flags 479 ); 480 481 if (cap->cc_kprocess == NULL) { 482 cap->cc_karg = karg; 483 cap->cc_kprocess = kprocess; 484 } 485 err = 0; 486 } else 487 err = EINVAL; 488 489 splx(s); 490 return err; 491 } 492 493 /* 494 * Register support for a non-key-related algorithm. This routine 495 * is called once for each such algorithm supported by a driver. 496 */ 497 int 498 crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen, 499 u_int32_t flags, 500 int (*newses)(void*, u_int32_t*, struct cryptoini*), 501 int (*freeses)(void*, u_int64_t), 502 int (*process)(void*, struct cryptop *, int), 503 void *arg) 504 { 505 struct cryptocap *cap; 506 int s, err; 507 508 s = splcrypto(); 509 510 cap = crypto_checkdriver(driverid); 511 /* NB: algorithms are in the range [1..max] */ 512 if (cap != NULL && 513 (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) { 514 /* 515 * XXX Do some performance testing to determine placing. 516 * XXX We probably need an auxiliary data structure that 517 * XXX describes relative performances. 518 */ 519 520 cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED; 521 cap->cc_max_op_len[alg] = maxoplen; 522 if (bootverbose) 523 printf("crypto: driver %u registers alg %u flags %u maxoplen %u\n" 524 , driverid 525 , alg 526 , flags 527 , maxoplen 528 ); 529 530 if (cap->cc_process == NULL) { 531 cap->cc_arg = arg; 532 cap->cc_newsession = newses; 533 cap->cc_process = process; 534 cap->cc_freesession = freeses; 535 cap->cc_sessions = 0; /* Unmark */ 536 } 537 err = 0; 538 } else 539 err = EINVAL; 540 541 splx(s); 542 return err; 543 } 544 545 /* 546 * Unregister a crypto driver. If there are pending sessions using it, 547 * leave enough information around so that subsequent calls using those 548 * sessions will correctly detect the driver has been unregistered and 549 * reroute requests. 550 */ 551 int 552 crypto_unregister(u_int32_t driverid, int alg) 553 { 554 int i, err, s; 555 u_int32_t ses; 556 struct cryptocap *cap; 557 558 s = splcrypto(); 559 560 cap = crypto_checkdriver(driverid); 561 if (cap != NULL && 562 (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) && 563 cap->cc_alg[alg] != 0) { 564 cap->cc_alg[alg] = 0; 565 cap->cc_max_op_len[alg] = 0; 566 567 /* Was this the last algorithm ? */ 568 for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++) 569 if (cap->cc_alg[i] != 0) 570 break; 571 572 if (i == CRYPTO_ALGORITHM_MAX + 1) { 573 ses = cap->cc_sessions; 574 bzero(cap, sizeof(struct cryptocap)); 575 if (ses != 0) { 576 /* 577 * If there are pending sessions, just mark as invalid. 578 */ 579 cap->cc_flags |= CRYPTOCAP_F_CLEANUP; 580 cap->cc_sessions = ses; 581 } 582 } 583 err = 0; 584 } else 585 err = EINVAL; 586 587 splx(s); 588 return err; 589 } 590 591 /* 592 * Unregister all algorithms associated with a crypto driver. 593 * If there are pending sessions using it, leave enough information 594 * around so that subsequent calls using those sessions will 595 * correctly detect the driver has been unregistered and reroute 596 * requests. 597 */ 598 int 599 crypto_unregister_all(u_int32_t driverid) 600 { 601 int i, err, s = splcrypto(); 602 u_int32_t ses; 603 struct cryptocap *cap; 604 605 cap = crypto_checkdriver(driverid); 606 if (cap != NULL) { 607 for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; i++) { 608 cap->cc_alg[i] = 0; 609 cap->cc_max_op_len[i] = 0; 610 } 611 ses = cap->cc_sessions; 612 bzero(cap, sizeof(struct cryptocap)); 613 if (ses != 0) { 614 /* 615 * If there are pending sessions, just mark as invalid. 616 */ 617 cap->cc_flags |= CRYPTOCAP_F_CLEANUP; 618 cap->cc_sessions = ses; 619 } 620 err = 0; 621 } else 622 err = EINVAL; 623 624 splx(s); 625 return err; 626 } 627 628 /* 629 * Clear blockage on a driver. The what parameter indicates whether 630 * the driver is now ready for cryptop's and/or cryptokop's. 631 */ 632 int 633 crypto_unblock(u_int32_t driverid, int what) 634 { 635 struct cryptocap *cap; 636 int needwakeup, err, s; 637 638 s = splcrypto(); 639 cap = crypto_checkdriver(driverid); 640 if (cap != NULL) { 641 needwakeup = 0; 642 if (what & CRYPTO_SYMQ) { 643 needwakeup |= cap->cc_qblocked; 644 cap->cc_qblocked = 0; 645 } 646 if (what & CRYPTO_ASYMQ) { 647 needwakeup |= cap->cc_kqblocked; 648 cap->cc_kqblocked = 0; 649 } 650 if (needwakeup) { 651 setsoftcrypto(softintr_cookie); 652 } 653 err = 0; 654 } else 655 err = EINVAL; 656 splx(s); 657 658 return err; 659 } 660 661 /* 662 * Dispatch a crypto request to a driver or queue 663 * it, to be processed by the kernel thread. 664 */ 665 int 666 crypto_dispatch(struct cryptop *crp) 667 { 668 u_int32_t hid = SESID2HID(crp->crp_sid); 669 int s, result; 670 671 s = splcrypto(); 672 673 cryptostats.cs_ops++; 674 675 #ifdef CRYPTO_TIMING 676 if (crypto_timing) 677 nanouptime(&crp->crp_tstamp); 678 #endif 679 if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) { 680 struct cryptocap *cap; 681 /* 682 * Caller marked the request to be processed 683 * immediately; dispatch it directly to the 684 * driver unless the driver is currently blocked. 685 */ 686 cap = crypto_checkdriver(hid); 687 if (cap && !cap->cc_qblocked) { 688 result = crypto_invoke(crp, 0); 689 if (result == ERESTART) { 690 /* 691 * The driver ran out of resources, mark the 692 * driver ``blocked'' for cryptop's and put 693 * the op on the queue. 694 */ 695 crypto_drivers[hid].cc_qblocked = 1; 696 TAILQ_INSERT_HEAD(&crp_q, crp, crp_next); 697 cryptostats.cs_blocks++; 698 } 699 } else { 700 /* 701 * The driver is blocked, just queue the op until 702 * it unblocks and the swi thread gets kicked. 703 */ 704 TAILQ_INSERT_TAIL(&crp_q, crp, crp_next); 705 result = 0; 706 } 707 } else { 708 int wasempty = TAILQ_EMPTY(&crp_q); 709 /* 710 * Caller marked the request as ``ok to delay''; 711 * queue it for the swi thread. This is desirable 712 * when the operation is low priority and/or suitable 713 * for batching. 714 */ 715 TAILQ_INSERT_TAIL(&crp_q, crp, crp_next); 716 if (wasempty) { 717 setsoftcrypto(softintr_cookie); 718 } 719 720 result = 0; 721 } 722 splx(s); 723 724 return result; 725 } 726 727 /* 728 * Add an asymetric crypto request to a queue, 729 * to be processed by the kernel thread. 730 */ 731 int 732 crypto_kdispatch(struct cryptkop *krp) 733 { 734 struct cryptocap *cap; 735 int s, result; 736 737 s = splcrypto(); 738 cryptostats.cs_kops++; 739 740 cap = crypto_checkdriver(krp->krp_hid); 741 if (cap && !cap->cc_kqblocked) { 742 result = crypto_kinvoke(krp, 0); 743 if (result == ERESTART) { 744 /* 745 * The driver ran out of resources, mark the 746 * driver ``blocked'' for cryptop's and put 747 * the op on the queue. 748 */ 749 crypto_drivers[krp->krp_hid].cc_kqblocked = 1; 750 TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next); 751 cryptostats.cs_kblocks++; 752 } 753 } else { 754 /* 755 * The driver is blocked, just queue the op until 756 * it unblocks and the swi thread gets kicked. 757 */ 758 TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next); 759 result = 0; 760 } 761 splx(s); 762 763 return result; 764 } 765 766 /* 767 * Dispatch an assymetric crypto request to the appropriate crypto devices. 768 */ 769 static int 770 crypto_kinvoke(struct cryptkop *krp, int hint) 771 { 772 u_int32_t hid; 773 int error; 774 775 /* Sanity checks. */ 776 if (krp == NULL) 777 return EINVAL; 778 if (krp->krp_callback == NULL) { 779 free(krp, M_XDATA); /* XXX allocated in cryptodev */ 780 return EINVAL; 781 } 782 783 for (hid = 0; hid < crypto_drivers_num; hid++) { 784 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) && 785 crypto_devallowsoft == 0) 786 continue; 787 if (crypto_drivers[hid].cc_kprocess == NULL) 788 continue; 789 if ((crypto_drivers[hid].cc_kalg[krp->krp_op] & 790 CRYPTO_ALG_FLAG_SUPPORTED) == 0) 791 continue; 792 break; 793 } 794 if (hid < crypto_drivers_num) { 795 krp->krp_hid = hid; 796 error = crypto_drivers[hid].cc_kprocess( 797 crypto_drivers[hid].cc_karg, krp, hint); 798 } else { 799 error = ENODEV; 800 } 801 802 if (error) { 803 krp->krp_status = error; 804 crypto_kdone(krp); 805 } 806 return 0; 807 } 808 809 #ifdef CRYPTO_TIMING 810 static void 811 crypto_tstat(struct cryptotstat *ts, struct timespec *tv) 812 { 813 struct timespec now, t; 814 815 nanouptime(&now); 816 t.tv_sec = now.tv_sec - tv->tv_sec; 817 t.tv_nsec = now.tv_nsec - tv->tv_nsec; 818 if (t.tv_nsec < 0) { 819 t.tv_sec--; 820 t.tv_nsec += 1000000000; 821 } 822 timespecadd(&ts->acc, &t, &t); 823 if (timespeccmp(&t, &ts->min, <)) 824 ts->min = t; 825 if (timespeccmp(&t, &ts->max, >)) 826 ts->max = t; 827 ts->count++; 828 829 *tv = now; 830 } 831 #endif 832 833 /* 834 * Dispatch a crypto request to the appropriate crypto devices. 835 */ 836 static int 837 crypto_invoke(struct cryptop *crp, int hint) 838 { 839 u_int32_t hid; 840 int (*process)(void*, struct cryptop *, int); 841 842 #ifdef CRYPTO_TIMING 843 if (crypto_timing) 844 crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp); 845 #endif 846 /* Sanity checks. */ 847 if (crp == NULL) 848 return EINVAL; 849 if (crp->crp_callback == NULL) { 850 crypto_freereq(crp); 851 return EINVAL; 852 } 853 if (crp->crp_desc == NULL) { 854 crp->crp_etype = EINVAL; 855 crypto_done(crp); 856 return 0; 857 } 858 859 hid = SESID2HID(crp->crp_sid); 860 if (hid < crypto_drivers_num) { 861 if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) 862 crypto_freesession(crp->crp_sid); 863 process = crypto_drivers[hid].cc_process; 864 } else { 865 process = NULL; 866 } 867 868 if (process == NULL) { 869 struct cryptodesc *crd; 870 u_int64_t nid; 871 872 /* 873 * Driver has unregistered; migrate the session and return 874 * an error to the caller so they'll resubmit the op. 875 */ 876 for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next) 877 crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI); 878 879 if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0) 880 crp->crp_sid = nid; 881 882 crp->crp_etype = EAGAIN; 883 crypto_done(crp); 884 return 0; 885 } else { 886 /* 887 * Invoke the driver to process the request. 888 */ 889 return (*process)(crypto_drivers[hid].cc_arg, crp, hint); 890 } 891 } 892 893 /* 894 * Release a set of crypto descriptors. 895 */ 896 void 897 crypto_freereq(struct cryptop *crp) 898 { 899 struct cryptodesc *crd; 900 int s; 901 902 if (crp == NULL) 903 return; 904 905 s = splcrypto(); 906 907 while ((crd = crp->crp_desc) != NULL) { 908 crp->crp_desc = crd->crd_next; 909 pool_put(&cryptodesc_pool, crd); 910 } 911 912 pool_put(&cryptop_pool, crp); 913 splx(s); 914 } 915 916 /* 917 * Acquire a set of crypto descriptors. 918 */ 919 struct cryptop * 920 crypto_getreq(int num) 921 { 922 struct cryptodesc *crd; 923 struct cryptop *crp; 924 int s; 925 926 s = splcrypto(); 927 928 if (crypto_pool_initialized == 0) { 929 pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0, 930 0, "cryptop", NULL); 931 pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0, 932 0, "cryptodesc", NULL); 933 crypto_pool_initialized = 1; 934 } 935 936 crp = pool_get(&cryptop_pool, 0); 937 if (crp == NULL) { 938 splx(s); 939 return NULL; 940 } 941 bzero(crp, sizeof(struct cryptop)); 942 943 while (num--) { 944 crd = pool_get(&cryptodesc_pool, 0); 945 if (crd == NULL) { 946 splx(s); 947 crypto_freereq(crp); 948 return NULL; 949 } 950 951 bzero(crd, sizeof(struct cryptodesc)); 952 crd->crd_next = crp->crp_desc; 953 crp->crp_desc = crd; 954 } 955 956 splx(s); 957 return crp; 958 } 959 960 /* 961 * Invoke the callback on behalf of the driver. 962 */ 963 void 964 crypto_done(struct cryptop *crp) 965 { 966 if (crp->crp_etype != 0) 967 cryptostats.cs_errs++; 968 #ifdef CRYPTO_TIMING 969 if (crypto_timing) 970 crypto_tstat(&cryptostats.cs_done, &crp->crp_tstamp); 971 #endif 972 /* 973 * On netbsd 1.6O, CBIMM does its wake_one() before the requestor 974 * has done its tsleep(). 975 */ 976 #ifndef __NetBSD__ 977 if (crp->crp_flags & CRYPTO_F_CBIMM) { 978 /* 979 * Do the callback directly. This is ok when the 980 * callback routine does very little (e.g. the 981 * /dev/crypto callback method just does a wakeup). 982 */ 983 #ifdef CRYPTO_TIMING 984 if (crypto_timing) { 985 /* 986 * NB: We must copy the timestamp before 987 * doing the callback as the cryptop is 988 * likely to be reclaimed. 989 */ 990 struct timespec t = crp->crp_tstamp; 991 crypto_tstat(&cryptostats.cs_cb, &t); 992 crp->crp_callback(crp); 993 crypto_tstat(&cryptostats.cs_finis, &t); 994 } else 995 #endif 996 crp->crp_callback(crp); 997 } else 998 #endif /* __NetBSD__ */ 999 { 1000 int s, wasempty; 1001 /* 1002 * Normal case; queue the callback for the thread. 1003 * 1004 * The return queue is manipulated by the swi thread 1005 * and, potentially, by crypto device drivers calling 1006 * back to mark operations completed. Thus we need 1007 * to mask both while manipulating the return queue. 1008 */ 1009 s = splcrypto(); 1010 wasempty = TAILQ_EMPTY(&crp_ret_q); 1011 TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next); 1012 if (wasempty) 1013 wakeup_one(&crp_ret_q); 1014 splx(s); 1015 } 1016 } 1017 1018 /* 1019 * Invoke the callback on behalf of the driver. 1020 */ 1021 void 1022 crypto_kdone(struct cryptkop *krp) 1023 { 1024 int s, wasempty; 1025 1026 if (krp->krp_status != 0) 1027 cryptostats.cs_kerrs++; 1028 /* 1029 * The return queue is manipulated by the swi thread 1030 * and, potentially, by crypto device drivers calling 1031 * back to mark operations completed. Thus we need 1032 * to mask both while manipulating the return queue. 1033 */ 1034 s = splcrypto(); 1035 wasempty = TAILQ_EMPTY(&crp_ret_kq); 1036 TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next); 1037 if (wasempty) 1038 wakeup_one(&crp_ret_q); 1039 splx(s); 1040 } 1041 1042 int 1043 crypto_getfeat(int *featp) 1044 { 1045 int hid, kalg, feat = 0; 1046 int s; 1047 1048 s = splcrypto(); 1049 1050 if (crypto_userasymcrypto == 0) 1051 goto out; 1052 1053 for (hid = 0; hid < crypto_drivers_num; hid++) { 1054 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) && 1055 crypto_devallowsoft == 0) { 1056 continue; 1057 } 1058 if (crypto_drivers[hid].cc_kprocess == NULL) 1059 continue; 1060 for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++) 1061 if ((crypto_drivers[hid].cc_kalg[kalg] & 1062 CRYPTO_ALG_FLAG_SUPPORTED) != 0) 1063 feat |= 1 << kalg; 1064 } 1065 out: 1066 splx(s); 1067 *featp = feat; 1068 return (0); 1069 } 1070 1071 /* 1072 * Software interrupt thread to dispatch crypto requests. 1073 */ 1074 static void 1075 cryptointr(void) 1076 { 1077 struct cryptop *crp, *submit; 1078 struct cryptkop *krp; 1079 struct cryptocap *cap; 1080 int result, hint, s; 1081 1082 printf("crypto softint\n"); 1083 cryptostats.cs_intrs++; 1084 s = splcrypto(); 1085 do { 1086 /* 1087 * Find the first element in the queue that can be 1088 * processed and look-ahead to see if multiple ops 1089 * are ready for the same driver. 1090 */ 1091 submit = NULL; 1092 hint = 0; 1093 TAILQ_FOREACH(crp, &crp_q, crp_next) { 1094 u_int32_t hid = SESID2HID(crp->crp_sid); 1095 cap = crypto_checkdriver(hid); 1096 if (cap == NULL || cap->cc_process == NULL) { 1097 /* Op needs to be migrated, process it. */ 1098 if (submit == NULL) 1099 submit = crp; 1100 break; 1101 } 1102 if (!cap->cc_qblocked) { 1103 if (submit != NULL) { 1104 /* 1105 * We stop on finding another op, 1106 * regardless whether its for the same 1107 * driver or not. We could keep 1108 * searching the queue but it might be 1109 * better to just use a per-driver 1110 * queue instead. 1111 */ 1112 if (SESID2HID(submit->crp_sid) == hid) 1113 hint = CRYPTO_HINT_MORE; 1114 break; 1115 } else { 1116 submit = crp; 1117 if ((submit->crp_flags & CRYPTO_F_BATCH) == 0) 1118 break; 1119 /* keep scanning for more are q'd */ 1120 } 1121 } 1122 } 1123 if (submit != NULL) { 1124 TAILQ_REMOVE(&crp_q, submit, crp_next); 1125 result = crypto_invoke(submit, hint); 1126 if (result == ERESTART) { 1127 /* 1128 * The driver ran out of resources, mark the 1129 * driver ``blocked'' for cryptop's and put 1130 * the request back in the queue. It would 1131 * best to put the request back where we got 1132 * it but that's hard so for now we put it 1133 * at the front. This should be ok; putting 1134 * it at the end does not work. 1135 */ 1136 /* XXX validate sid again? */ 1137 crypto_drivers[SESID2HID(submit->crp_sid)].cc_qblocked = 1; 1138 TAILQ_INSERT_HEAD(&crp_q, submit, crp_next); 1139 cryptostats.cs_blocks++; 1140 } 1141 } 1142 1143 /* As above, but for key ops */ 1144 TAILQ_FOREACH(krp, &crp_kq, krp_next) { 1145 cap = crypto_checkdriver(krp->krp_hid); 1146 if (cap == NULL || cap->cc_kprocess == NULL) { 1147 /* Op needs to be migrated, process it. */ 1148 break; 1149 } 1150 if (!cap->cc_kqblocked) 1151 break; 1152 } 1153 if (krp != NULL) { 1154 TAILQ_REMOVE(&crp_kq, krp, krp_next); 1155 result = crypto_kinvoke(krp, 0); 1156 if (result == ERESTART) { 1157 /* 1158 * The driver ran out of resources, mark the 1159 * driver ``blocked'' for cryptkop's and put 1160 * the request back in the queue. It would 1161 * best to put the request back where we got 1162 * it but that's hard so for now we put it 1163 * at the front. This should be ok; putting 1164 * it at the end does not work. 1165 */ 1166 /* XXX validate sid again? */ 1167 crypto_drivers[krp->krp_hid].cc_kqblocked = 1; 1168 TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next); 1169 cryptostats.cs_kblocks++; 1170 } 1171 } 1172 } while (submit != NULL || krp != NULL); 1173 splx(s); 1174 } 1175 1176 /* 1177 * Kernel thread to do callbacks. 1178 */ 1179 static void 1180 cryptoret(void) 1181 { 1182 struct cryptop *crp; 1183 struct cryptkop *krp; 1184 int s; 1185 1186 s = splcrypto(); 1187 for (;;) { 1188 crp = TAILQ_FIRST(&crp_ret_q); 1189 if (crp != NULL) 1190 TAILQ_REMOVE(&crp_ret_q, crp, crp_next); 1191 krp = TAILQ_FIRST(&crp_ret_kq); 1192 if (krp != NULL) 1193 TAILQ_REMOVE(&crp_ret_kq, krp, krp_next); 1194 1195 if (crp != NULL || krp != NULL) { 1196 splx(s); /* lower ipl for callbacks */ 1197 if (crp != NULL) { 1198 #ifdef CRYPTO_TIMING 1199 if (crypto_timing) { 1200 /* 1201 * NB: We must copy the timestamp before 1202 * doing the callback as the cryptop is 1203 * likely to be reclaimed. 1204 */ 1205 struct timespec t = crp->crp_tstamp; 1206 crypto_tstat(&cryptostats.cs_cb, &t); 1207 crp->crp_callback(crp); 1208 crypto_tstat(&cryptostats.cs_finis, &t); 1209 } else 1210 #endif 1211 crp->crp_callback(crp); 1212 } 1213 if (krp != NULL) 1214 krp->krp_callback(krp); 1215 s = splcrypto(); 1216 } else { 1217 (void) tsleep(&crp_ret_q, PLOCK, "crypto_wait", 0); 1218 cryptostats.cs_rets++; 1219 } 1220 } 1221 } 1222 1223 static void 1224 deferred_crypto_thread(void *arg) 1225 { 1226 int error; 1227 1228 error = kthread_create1((void (*)(void*)) cryptoret, NULL, 1229 &cryptoproc, "cryptoret"); 1230 if (error) { 1231 printf("crypto_init: cannot start cryptoret thread; error %d", 1232 error); 1233 crypto_destroy(); 1234 } 1235 } 1236 1237 #ifdef __FreeBSD__ 1238 /* 1239 * Initialization code, both for static and dynamic loading. 1240 */ 1241 static int 1242 crypto_modevent(module_t mod, int type, void *unused) 1243 { 1244 int error = EINVAL; 1245 1246 switch (type) { 1247 case MOD_LOAD: 1248 error = crypto_init(); 1249 if (error == 0 && bootverbose) 1250 printf("crypto: <crypto core>\n"); 1251 break; 1252 case MOD_UNLOAD: 1253 /*XXX disallow if active sessions */ 1254 error = 0; 1255 crypto_destroy(); 1256 break; 1257 } 1258 return error; 1259 } 1260 static moduledata_t crypto_mod = { 1261 "crypto", 1262 crypto_modevent, 1263 0 1264 }; 1265 1266 MODULE_VERSION(crypto, 1); 1267 DECLARE_MODULE(crypto, crypto_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 1268 #endif /* __FreeBSD__ */ 1269 1270 1271