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 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Niagara 2 Random Number Generator (RNG) driver 30 */ 31 32 #include <sys/types.h> 33 #include <sys/sysmacros.h> 34 #include <sys/modctl.h> 35 #include <sys/conf.h> 36 #include <sys/devops.h> 37 #include <sys/cmn_err.h> 38 #include <sys/ksynch.h> 39 #include <sys/kmem.h> 40 #include <sys/stat.h> 41 #include <sys/open.h> 42 #include <sys/file.h> 43 #include <sys/ddi.h> 44 #include <sys/sunddi.h> 45 #include <sys/param.h> 46 #include <sys/cpuvar.h> 47 #include <sys/disp.h> 48 #include <sys/hsvc.h> 49 #include <sys/machsystm.h> 50 #include <sys/hypervisor_api.h> 51 #include <sys/n2rng.h> 52 53 static int n2rng_attach(dev_info_t *, ddi_attach_cmd_t); 54 static int n2rng_detach(dev_info_t *, ddi_detach_cmd_t); 55 static int n2rng_suspend(n2rng_t *); 56 static int n2rng_resume(n2rng_t *); 57 int n2rng_herr2kerr(uint64_t); 58 int n2rng_logic_test(n2rng_t *); 59 int n2rng_noise_gen_test_set(void); 60 int n2rng_init(n2rng_t *n2rng); 61 int n2rng_uninit(n2rng_t *n2rng); 62 63 static uint64_t sticks_per_usec(void); 64 u_longlong_t gettick(void); 65 66 static void n2rng_config_task(void * targ); 67 68 /* 69 * Device operations. 70 */ 71 72 static struct dev_ops devops = { 73 DEVO_REV, /* devo_rev */ 74 0, /* devo_refcnt */ 75 nodev, /* devo_getinfo */ 76 nulldev, /* devo_identify */ 77 nulldev, /* devo_probe */ 78 n2rng_attach, /* devo_attach */ 79 n2rng_detach, /* devo_detach */ 80 nodev, /* devo_reset */ 81 NULL, /* devo_cb_ops */ 82 NULL, /* devo_bus_ops */ 83 ddi_power /* devo_power */ 84 }; 85 86 /* 87 * Module linkage. 88 */ 89 static struct modldrv modldrv = { 90 &mod_driverops, /* drv_modops */ 91 "N2 RNG Driver v%I%", /* drv_linkinfo */ 92 &devops, /* drv_dev_ops */ 93 }; 94 95 static struct modlinkage modlinkage = { 96 MODREV_1, /* ml_rev */ 97 &modldrv, /* ml_linkage */ 98 NULL 99 }; 100 101 /* 102 * Driver globals Soft state. 103 */ 104 static void *n2rng_softstate = NULL; 105 106 /* 107 * Hypervisor RNG information. 108 */ 109 static uint64_t rng_min_ver; /* negotiated RNG API minor version */ 110 static boolean_t rng_hsvc_available = B_FALSE; 111 112 static hsvc_info_t rng_hsvc = { 113 HSVC_REV_1, NULL, HSVC_GROUP_RNG, RNG_MAJOR_VER, 114 RNG_MINOR_VER, "n2rng" 115 }; 116 117 /* 118 * DDI entry points. 119 */ 120 int 121 _init(void) 122 { 123 int rv; 124 125 rv = ddi_soft_state_init(&n2rng_softstate, sizeof (n2rng_t), 1); 126 if (rv != 0) { 127 /* this should *never* happen! */ 128 return (rv); 129 } 130 131 if ((rv = mod_install(&modlinkage)) != 0) { 132 /* cleanup here */ 133 ddi_soft_state_fini(&n2rng_softstate); 134 return (rv); 135 } 136 137 return (0); 138 } 139 140 int 141 _fini(void) 142 { 143 int rv; 144 145 rv = mod_remove(&modlinkage); 146 if (rv == 0) { 147 /* cleanup here */ 148 ddi_soft_state_fini(&n2rng_softstate); 149 } 150 151 return (rv); 152 } 153 154 int 155 _info(struct modinfo *modinfop) 156 { 157 return (mod_info(&modlinkage, modinfop)); 158 } 159 160 static int 161 n2rng_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 162 { 163 n2rng_t *n2rng = NULL; 164 int instance; 165 int rv; 166 167 instance = ddi_get_instance(dip); 168 DBG1(NULL, DATTACH, "n2rng_attach called, instance %d", instance); 169 /* 170 * Only instance 0 of n2rng driver is allowed. 171 */ 172 if (instance != 0) { 173 n2rng_diperror(dip, "only one instance (0) allowed"); 174 return (DDI_FAILURE); 175 } 176 177 switch (cmd) { 178 case DDI_RESUME: 179 n2rng = (n2rng_t *)ddi_get_soft_state(n2rng_softstate, 180 instance); 181 if (n2rng == NULL) { 182 n2rng_diperror(dip, "no soft state in attach"); 183 return (DDI_FAILURE); 184 } 185 return (n2rng_resume(n2rng)); 186 187 case DDI_ATTACH: 188 break; 189 default: 190 return (DDI_FAILURE); 191 } 192 193 rv = ddi_soft_state_zalloc(n2rng_softstate, instance); 194 if (rv != DDI_SUCCESS) { 195 n2rng_diperror(dip, "unable to allocate soft state"); 196 return (DDI_FAILURE); 197 } 198 n2rng = (n2rng_t *)ddi_get_soft_state(n2rng_softstate, instance); 199 ASSERT(n2rng != NULL); 200 n2rng->n_dip = dip; 201 202 mutex_init(&n2rng->n_health_check_mutex, NULL, MUTEX_DRIVER, NULL); 203 204 if ((rv = hsvc_register(&rng_hsvc, &rng_min_ver)) != 0) { 205 cmn_err(CE_WARN, "%s: cannot negotiate hypervisor services " 206 "group: 0x%lx major: 0x%lx minor: 0x%lx errno: %d", 207 rng_hsvc.hsvc_modname, rng_hsvc.hsvc_group, 208 rng_hsvc.hsvc_major, rng_hsvc.hsvc_minor, rv); 209 ddi_soft_state_free(n2rng_softstate, instance); 210 mutex_destroy(&n2rng->n_health_check_mutex); 211 return (DDI_FAILURE); 212 } 213 rng_hsvc_available = B_TRUE; 214 215 /* Allocate single thread task queue for rng diags and registration */ 216 n2rng->n_taskq = ddi_taskq_create(dip, "n2rng_taskq", 1, 217 TASKQ_DEFAULTPRI, 0); 218 219 if (n2rng->n_taskq == NULL) { 220 n2rng_diperror(dip, "ddi_taskq_create() failed"); 221 goto errorexit; 222 } 223 224 /* No locking, but it is okay */ 225 n2rng->n_sticks_per_usec = sticks_per_usec(); 226 /* 227 * The first product will likely be around 4 billion, so we 228 * use uint64_t to avoid integer overflow. 229 */ 230 n2rng->n_anlg_settle_cycles = (uint64_t)RNG_CTL_SETTLE_NS * 231 n2rng->n_sticks_per_usec / 1000; 232 233 /* 234 * Set some plausible state into the preferred 235 * configuration. The intent is that the health check, below, 236 * will immediately overwrite it. If we are not in a control 237 * domain, this stuff will have no effect. 238 */ 239 n2rng->n_preferred_config.ctlwds[0].word = 0; 240 n2rng->n_preferred_config.ctlwds[0].fields.rnc_anlg_sel = 241 N2RNG_NOANALOGOUT; 242 n2rng->n_preferred_config.ctlwds[0].fields.rnc_cnt = 243 RNG_DEFAULT_ACCUMULATE_CYCLES; 244 n2rng->n_preferred_config.ctlwds[0].fields.rnc_mode = 245 RNG_MODE_NORMAL; 246 n2rng->n_preferred_config.ctlwds[1].word = 247 n2rng->n_preferred_config.ctlwds[0].word; 248 n2rng->n_preferred_config.ctlwds[2].word = 249 n2rng->n_preferred_config.ctlwds[0].word; 250 n2rng->n_preferred_config.ctlwds[3].word = 251 n2rng->n_preferred_config.ctlwds[0].word; 252 n2rng->n_preferred_config.ctlwds[0].fields.rnc_vcoctl = 1; 253 n2rng->n_preferred_config.ctlwds[0].fields.rnc_selbits = 1; 254 n2rng->n_preferred_config.ctlwds[1].fields.rnc_vcoctl = 2; 255 n2rng->n_preferred_config.ctlwds[1].fields.rnc_selbits = 2; 256 n2rng->n_preferred_config.ctlwds[2].fields.rnc_vcoctl = 3; 257 n2rng->n_preferred_config.ctlwds[2].fields.rnc_selbits = 4; 258 n2rng->n_preferred_config.ctlwds[3].fields.rnc_vcoctl = 0; 259 n2rng->n_preferred_config.ctlwds[3].fields.rnc_selbits = 7; 260 261 /* Dispatch task to configure the RNG and register with KCF */ 262 if (ddi_taskq_dispatch(n2rng->n_taskq, n2rng_config_task, 263 (void *)n2rng, DDI_SLEEP) != DDI_SUCCESS) { 264 n2rng_diperror(dip, "ddi_taskq_dispatch() failed"); 265 goto errorexit; 266 } 267 268 return (DDI_SUCCESS); 269 270 errorexit: 271 if (rng_hsvc_available == B_TRUE) { 272 (void) hsvc_unregister(&rng_hsvc); 273 rng_hsvc_available = B_FALSE; 274 } 275 276 if (n2rng->n_taskq != NULL) { 277 ddi_taskq_destroy(n2rng->n_taskq); 278 n2rng->n_taskq = NULL; 279 } 280 281 mutex_destroy(&n2rng->n_health_check_mutex); 282 ddi_soft_state_free(n2rng_softstate, instance); 283 284 return (DDI_FAILURE); 285 } 286 287 static int 288 n2rng_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 289 { 290 int instance; 291 int rv; 292 n2rng_t *n2rng; 293 294 instance = ddi_get_instance(dip); 295 n2rng = (n2rng_t *)ddi_get_soft_state(n2rng_softstate, instance); 296 if (n2rng == NULL) { 297 n2rng_diperror(dip, "no soft state in detach"); 298 return (DDI_FAILURE); 299 } 300 301 switch (cmd) { 302 case DDI_SUSPEND: 303 return (n2rng_suspend(n2rng)); 304 case DDI_DETACH: 305 break; 306 default: 307 return (DDI_FAILURE); 308 } 309 310 /* Destroy task queue first to insure configuration has completed */ 311 if (n2rng->n_taskq != NULL) { 312 ddi_taskq_destroy(n2rng->n_taskq); 313 n2rng->n_taskq = NULL; 314 } 315 316 /* unregister with KCF---also tears down FIPS state */ 317 rv = n2rng_uninit(n2rng) ? DDI_FAILURE : DDI_SUCCESS; 318 319 if (rng_hsvc_available == B_TRUE) { 320 (void) hsvc_unregister(&rng_hsvc); 321 rng_hsvc_available = B_FALSE; 322 } 323 324 mutex_destroy(&n2rng->n_health_check_mutex); 325 326 ddi_soft_state_free(n2rng_softstate, instance); 327 328 return (rv); 329 } 330 331 /*ARGSUSED*/ 332 static int 333 n2rng_suspend(n2rng_t *n2rng) 334 { 335 return (DDI_SUCCESS); 336 } 337 338 /*ARGSUSED*/ 339 static int 340 n2rng_resume(n2rng_t *n2rng) 341 { 342 int rv; 343 344 /* assume clock is same speed, all data structures intact. */ 345 rv = n2rng_do_health_check(n2rng); 346 switch (rv) { 347 case 0: 348 case EPERM: 349 break; 350 default: 351 cmn_err(CE_WARN, "n2rng: n2rng_resume: health check failed. " 352 "Unregistering from encryption framework"); 353 n2rng->n_flags |= N2RNG_FAILED; 354 (void) n2rng_uninit(n2rng); 355 break; 356 } 357 358 return (DDI_SUCCESS); 359 } 360 361 /* 362 * Map hypervisor error code to solaris. Only 363 * H_ENORADDR, H_EBADALIGN, H_EWOULDBLOCK, and EIO 364 * are meaningful to this device. Any other error 365 * codes are mapped EINVAL. 366 */ 367 int 368 n2rng_herr2kerr(uint64_t hv_errcode) 369 { 370 int s_errcode; 371 372 switch (hv_errcode) { 373 case H_EWOULDBLOCK: 374 s_errcode = EWOULDBLOCK; 375 break; 376 case H_ENORADDR: 377 case H_EBADALIGN: 378 case H_EIO: 379 s_errcode = EIO; 380 break; 381 case H_EOK: 382 s_errcode = 0; 383 break; 384 case H_ENOACCESS: 385 s_errcode = EPERM; 386 break; 387 default: 388 s_errcode = EINVAL; 389 break; 390 } 391 return (s_errcode); 392 } 393 394 /* 395 * Waits approximately delay_sticks counts of the stick register. 396 * Times shorter than one sys clock tick (10ms on most systems) are 397 * done by busy waiting. 398 */ 399 void 400 cyclesleep(n2rng_t *n2rng, uint64_t delay_sticks) 401 { 402 uint64_t end_stick = gettick() + delay_sticks; 403 int64_t sticks_to_wait; 404 clock_t sys_ticks_to_wait; 405 clock_t usecs_to_wait; 406 407 /*CONSTCOND*/ 408 while (1) { 409 sticks_to_wait = end_stick - gettick(); 410 if (sticks_to_wait <= 0) { 411 return; 412 } 413 414 usecs_to_wait = sticks_to_wait / n2rng->n_sticks_per_usec; 415 sys_ticks_to_wait = drv_usectohz(usecs_to_wait); 416 417 if (sys_ticks_to_wait > 0) { 418 /* sleep */ 419 delay(sys_ticks_to_wait); 420 } else if (usecs_to_wait > 0) { 421 /* busy wait */ 422 drv_usecwait(usecs_to_wait); 423 } 424 } 425 } 426 427 static void 428 log_internal_errors(uint64_t hverr, char *fname) 429 { 430 switch (hverr) { 431 case H_EBADALIGN: 432 cmn_err(CE_WARN, 433 "n2rng: internal alignment " 434 "problem"); 435 break; 436 case H_ENORADDR: 437 cmn_err(CE_WARN, "n2rng: internal " 438 "invalid address"); 439 break; 440 default: 441 cmn_err(CE_NOTE, 442 "n2rng: %s " 443 "unexpectedly " 444 "returned hverr %ld", fname, hverr); 445 break; 446 } 447 } 448 449 /* 450 * Collects a buffer full of bits, using the specified setup. numbytes 451 * must be a multiple of 8. If a sub-operation fails with EIO (handle 452 * mismatch), returns EIO. If collect_setupp is NULL, the current 453 * setup is used. If exit_setupp is NULL, the control configuratin 454 * and state are not set at exit. WARNING: the buffer must be 8-byte 455 * aligned and in contiguous physical addresses. Contiguousness is 456 * not checked! 457 */ 458 int 459 n2rng_collect_diag_bits(n2rng_t *n2rng, n2rng_setup_t *collect_setupp, 460 void *buffer, int numbytes, n2rng_setup_t *exit_setupp, 461 uint64_t exitstate) 462 { 463 int rv; 464 int override_rv = 0; 465 uint64_t hverr; 466 int i; 467 uint64_t tdelta; 468 n2rng_setup_t setupbuffer[2]; 469 n2rng_setup_t *setupcontigp; 470 uint64_t setupphys; 471 int numchunks; 472 boolean_t rnglooping; 473 474 if (numbytes % sizeof (uint64_t)) { 475 return (EINVAL); 476 } 477 478 if ((uint64_t)buffer % sizeof (uint64_t) != 0) { 479 return (EINVAL); 480 } 481 482 numchunks = ((numbytes / sizeof (uint64_t)) + RNG_DIAG_CHUNK_SIZE - 1) 483 / RNG_DIAG_CHUNK_SIZE; 484 /* 485 * Use setupbuffer[0] if it is contiguous, otherwise 486 * setupbuffer[1]. 487 */ 488 setupcontigp = &setupbuffer[ 489 CONTIGUOUS(&setupbuffer[0], n2rng_setup_t) ? 0 : 1]; 490 setupphys = va_to_pa(setupcontigp); 491 492 /* 493 * If a non-null collect_setupp pointer has been provided, 494 * push the specified setup into the hardware. 495 */ 496 if (collect_setupp != NULL) { 497 /* copy the specified state to the aligned buffer */ 498 *setupcontigp = *collect_setupp; 499 rnglooping = B_TRUE; 500 while (rnglooping) { 501 hverr = hv_rng_ctl_write(setupphys, 502 CTL_STATE_HEALTHCHECK, 503 n2rng->n_anlg_settle_cycles, &tdelta); 504 rv = n2rng_herr2kerr(hverr); 505 switch (hverr) { 506 case 0: 507 rnglooping = B_FALSE; 508 break; 509 case H_EIO: /* control yanked from us */ 510 case H_ENOACCESS: /* We are not control domain */ 511 return (rv); 512 case H_EWOULDBLOCK: 513 cyclesleep(n2rng, tdelta); 514 break; 515 default: 516 log_internal_errors(hverr, "hv_rng_ctl_write"); 517 override_rv = rv; 518 goto restore_state; 519 } 520 } /* while (rnglooping) */ 521 } /* if (collect_setupp != NULL) */ 522 523 /* If the caller asks for some bytes, collect the data */ 524 if (numbytes > 0) { 525 for (i = 0; i < numchunks; i++) { 526 size_t thisnumbytes = (i == numchunks - 1) ? 527 numbytes - i * (RNG_DIAG_CHUNK_SIZE * 528 sizeof (uint64_t)) : 529 RNG_DIAG_CHUNK_SIZE * sizeof (uint64_t); 530 /* try until we successfully read a word of data */ 531 rnglooping = B_TRUE; 532 while (rnglooping) { 533 hverr = hv_rng_data_read_diag( 534 va_to_pa((uint64_t *)buffer + 535 RNG_DIAG_CHUNK_SIZE * i), 536 thisnumbytes, &tdelta); 537 rv = n2rng_herr2kerr(hverr); 538 switch (hverr) { 539 case 0: 540 rnglooping = B_FALSE; 541 break; 542 case H_EIO: 543 case H_ENOACCESS: 544 return (rv); 545 case H_EWOULDBLOCK: 546 cyclesleep(n2rng, tdelta); 547 break; 548 default: 549 log_internal_errors(hverr, 550 "hv_rng_data_read_diag"); 551 override_rv = rv; 552 goto restore_state; 553 } 554 } /* while (!rnglooping) */ 555 } /* for */ 556 } /* if */ 557 558 restore_state: 559 560 /* restore the preferred configuration and set exit state */ 561 if (exit_setupp != NULL) { 562 563 *setupcontigp = *exit_setupp; 564 rnglooping = B_TRUE; 565 while (rnglooping) { 566 hverr = hv_rng_ctl_write(setupphys, exitstate, 567 n2rng->n_anlg_settle_cycles, &tdelta); 568 rv = n2rng_herr2kerr(hverr); 569 switch (hverr) { 570 case 0: 571 case H_EIO: /* control yanked from us */ 572 case H_EINVAL: /* some external error, probably */ 573 case H_ENOACCESS: /* We are not control domain */ 574 rnglooping = B_FALSE; 575 break; 576 case H_EWOULDBLOCK: 577 cyclesleep(n2rng, tdelta); 578 break; 579 580 default: 581 rnglooping = B_FALSE; 582 log_internal_errors(hverr, "hv_rng_ctl_write"); 583 break; 584 } 585 } /* while */ 586 } /* if */ 587 588 /* 589 * override_rv takes care of the case where we abort becuase 590 * of some error, but still want to restore the peferred state 591 * and return the first error, even if other error occur. 592 */ 593 return (override_rv ? override_rv : rv); 594 } 595 596 int 597 n2rng_getentropy(n2rng_t *n2rng, void *buffer, size_t size) 598 { 599 int i, rv = 0; /* so it works if size is zero */ 600 uint64_t hverr; 601 uint64_t *buffer_w = (uint64_t *)buffer; 602 int num_w = size / sizeof (uint64_t); 603 uint64_t randval; 604 uint64_t randvalphys = va_to_pa(&randval); 605 uint64_t tdelta; 606 int failcount = 0; 607 boolean_t rnglooping; 608 609 for (i = 0; i < num_w; i++) { 610 rnglooping = B_TRUE; 611 while (rnglooping) { 612 hverr = hv_rng_data_read(randvalphys, &tdelta); 613 rv = n2rng_herr2kerr(hverr); 614 switch (hverr) { 615 case H_EOK: 616 buffer_w[i] = randval; 617 failcount = 0; 618 rnglooping = B_FALSE; 619 break; 620 case H_EIO: 621 /* 622 * A health check is in progress. 623 * Wait RNG_RETRY_HLCHK_USECS and fail 624 * after RNG_MAX_DATA_READ_ATTEMPTS 625 * failures. 626 */ 627 if (++failcount > RNG_MAX_DATA_READ_ATTEMPTS) { 628 goto exitpoint; 629 } else { 630 delay(drv_usectohz( 631 RNG_RETRY_HLCHK_USECS)); 632 } 633 break; 634 case H_EWOULDBLOCK: 635 cyclesleep(n2rng, tdelta); 636 break; 637 default: 638 log_internal_errors(hverr, "hv_rng_data_read"); 639 goto exitpoint; 640 } 641 } /* while */ 642 } /* for */ 643 644 exitpoint: 645 646 return (rv); 647 } 648 649 static uint64_t 650 sticks_per_usec(void) 651 { 652 uint64_t starttick = gettick(); 653 hrtime_t starttime = gethrtime(); 654 uint64_t endtick; 655 hrtime_t endtime; 656 657 delay(2); 658 659 endtick = gettick(); 660 endtime = gethrtime(); 661 662 return ((1000 * (endtick - starttick)) / (endtime - starttime)); 663 } 664 665 /* 666 * n2rng_config_task() 667 * 668 * Runs health checks on the RNG hardware 669 * Configures the RNG hardware 670 * Registers with crypto framework if successful. 671 */ 672 static void 673 n2rng_config_task(void * targ) 674 { 675 int rv; 676 n2rng_t *n2rng = (n2rng_t *)targ; 677 678 thread_affinity_set(curthread, CPU_CURRENT); 679 rv = n2rng_do_health_check(n2rng); 680 thread_affinity_clear(curthread); 681 682 switch (rv) { 683 case 0: 684 /* We are a control domain. Success. */ 685 break; 686 case EPERM: 687 /* We must not be a control domain, declare success. */ 688 rv = 0; 689 break; 690 default: 691 goto errorexit; 692 } 693 694 /* Register with KCF and initialize FIPS state */ 695 rv = n2rng_init(n2rng); 696 if (rv != DDI_SUCCESS) { 697 goto errorexit; 698 } 699 700 n2rng->n_flags &= ~N2RNG_FAILED; 701 return; 702 703 errorexit: 704 cmn_err(CE_WARN, "n2rng_config_task: RNG configuration failed"); 705 n2rng->n_flags |= N2RNG_FAILED; 706 } 707