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