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 #include <sys/types.h> 29 #include <sys/sysmacros.h> 30 #include <sys/modctl.h> 31 #include <sys/conf.h> 32 #include <sys/devops.h> 33 #include <sys/cmn_err.h> 34 #include <sys/kmem.h> 35 #include <sys/stat.h> 36 #include <sys/open.h> 37 #include <sys/file.h> 38 #include <sys/ddi.h> 39 #include <sys/sunddi.h> 40 #include <sys/cpuvar.h> 41 #include <sys/disp.h> 42 #include <sys/hsvc.h> 43 #include <sys/machsystm.h> 44 #include <sys/param.h> 45 #include <sys/hypervisor_api.h> 46 #include <sys/n2rng.h> 47 48 /* 49 * There are 3 noise cells each with its own oscillator, and each 50 * oscillator can be set to 4 different bias setttings. The bias 51 * setting controls the nominal frequency of the oscillator. The 3 52 * and 4 and hardcoded throughout this file. 53 */ 54 55 #define BITS_IN(type) (8 * sizeof (type)) 56 #define EXTRACTBIT64(val, bit) (((val) >> (bit)) & 1UL) 57 58 /* 59 * Policy settings 60 */ 61 /* Log2 of the number of bits */ 62 #define SETTLECYCLES 1000000 63 #define NORMAL_BYPASS 1 64 #define NUMOSC 3 65 #define LOG2_DATA_WORDS 15 66 #define DATA_WORDS (1 << LOG2_DATA_WORDS) 67 68 #define ENTROPY_PASS_VALUE 150000000ULL 69 70 /* 71 * There is a hardware bug that causes the RNG_DATA register to 72 * occasionally be read one cycle before the specifed time. 73 * LOGIC_TEST_EXPECTED_M1 is the value one cycle before 74 * LOGIC_TEST_CYCLES. And there is a second bug that causes the read 75 * to be delayed. We have seen delays of about 150 cycles, but do not 76 * know that maximum that could possibly occur. 77 * 78 * We collect LOGIC_TEST_WORDS words using a diagnostic read with all 79 * entropy turned off. The first one we skip, becuase we have no 80 * knowledge of the time since the last read. We check that the 81 * remaining values fall in the window of values that should occur 82 * between LOGIC_TEST_CYCLES - 1 and LOGIC_TEST_CYCLES + 83 * LOGIC_TEST_BUG_MAX. As further protecion against false positives, 84 * we report success if the the number of mismatches does not exceed 85 * LOGIC_TEST_ERRORS_ALLOWED. 86 */ 87 88 #define LOGIC_TEST_CYCLES 38859 89 #define LOGIC_TEST_EXPECTED_M1 0xb8820c7bd387e32cULL 90 #define LOGIC_TEST_BUG_MAX 400 91 #define LOGIC_TEST_WORDS 8 /* includes first one, unused */ 92 #define LOGIC_TEST_ERRORS_ALLOWED 1 93 #define RNG_POLY 0x231dcee91262b8a3ULL 94 #define ENTDIVISOR (((1ULL << LOG_VAL_SCALE) + 500ULL) / 1000ULL) 95 96 #define ENCODEBIAS(osc, bias) (((bias) & 0x3) << (2 * (osc))) 97 #define EXTRACTBIAS(blob, osc) (((blob) >> (2 * (osc))) & 0x3) 98 99 extern int n2rng_herr2kerr(uint64_t hv_errcode); 100 101 102 /* 103 * Each value is a representation of the polynomail bit_i * x^i, where 104 * i=0 corresponds to the least significant bit of the word. The 105 * modulus polynomial is x^64 + the interpretation of poly. Out is 106 * set to in * x^exp mod moduluspolynomial. This corresponds to 107 * running the LFSR exp cycles. This implemenation directly simulates 108 * the lfsr. It's running time is O(exp), but the constant is small. 109 * (This code was taken verbatim from Legion.) 110 */ 111 static void 112 lfsr64_adv_seq(uint64_t poly, uint64_t in, uint64_t exp, uint64_t *out) 113 { 114 int i; 115 uint64_t res = in; 116 117 for (i = 0; i < exp; i++) { 118 if (res & 0x8000000000000000ULL) { 119 res = (res << 1) ^ poly; 120 } else { 121 res <<= 1; 122 } 123 } 124 125 *out = res; 126 } 127 128 129 int 130 n2rng_logic_test(n2rng_t *n2rng) 131 { 132 n2rng_setup_t logictest; 133 uint64_t buffer[2]; 134 uint64_t reg; 135 int rv; 136 int i, j; 137 int correctcount = 0; 138 139 /* 140 * This test runs the RNG with no entropy for 141 * LOGIC_TEST_CYCLES cycles. Ideally the value would be be 142 * LOGIC_TEST_RESULT, but because of the RNG bug, the actual 143 * register read may be delayed by upto LOGIC_TEST_BUG_MAX 144 * cycles. So we simulate over that window, and a match 145 * occurs, we report success. 146 */ 147 148 logictest.ctlwds[0].word = 0; 149 logictest.ctlwds[0].fields.rnc_anlg_sel = N2RNG_NOANALOGOUT; 150 logictest.ctlwds[1] = logictest.ctlwds[0]; 151 logictest.ctlwds[2] = logictest.ctlwds[0]; 152 logictest.ctlwds[3] = logictest.ctlwds[0]; 153 logictest.ctlwds[3].fields.rnc_mode = 1; 154 logictest.ctlwds[3].fields.rnc_cnt = LOGIC_TEST_CYCLES - 2; 155 156 /* read LOGIC_TEST_WORDS 64-bit words */ 157 158 159 rv = n2rng_collect_diag_bits(n2rng, &logictest, buffer, 160 LOGIC_TEST_WORDS * sizeof (uint64_t), 161 &n2rng->n_preferred_config, n2rng->n_rng_state); 162 if (rv) { 163 cmn_err(CE_WARN, 164 "n2rng: n2rng_collect_diag_bits fails with 0x%x", rv); 165 return (rv); 166 } 167 168 reg = LOGIC_TEST_EXPECTED_M1; 169 for (i = 0; i <= LOGIC_TEST_BUG_MAX; i++) { 170 for (j = 1; j < LOGIC_TEST_WORDS; ++j) { 171 if (buffer[j] == reg) { 172 ++correctcount; 173 } 174 } 175 /* advance reg by one step */ 176 lfsr64_adv_seq(RNG_POLY, reg, 1, ®); 177 } 178 179 if (correctcount < LOGIC_TEST_WORDS - 1 - LOGIC_TEST_ERRORS_ALLOWED) { 180 cmn_err(CE_WARN, "n2rng: logic error in rng."); 181 return (EIO); 182 } 183 184 return (0); 185 } 186 187 188 /* 189 * gets the metric for the specified state. 190 */ 191 int 192 n2rng_collect_metrics(n2rng_t *n2rng, n2rng_setup_t *setupp, 193 n2rng_setup_t *exit_setupp, 194 uint64_t exit_state, n2rng_osc_perf_t *metricp) 195 { 196 int rv; 197 int bufsize; 198 uint64_t *buffer = NULL; 199 200 201 bufsize = DATA_WORDS * sizeof (uint64_t); 202 buffer = (uint64_t *)contig_mem_alloc_align(bufsize, 203 CONTIG_ALIGNMENT); 204 if (buffer == NULL) { 205 return (ENOMEM); 206 } 207 208 rv = n2rng_collect_diag_bits(n2rng, setupp, buffer, bufsize, 209 exit_setupp, exit_state); 210 if (rv) { 211 cmn_err(CE_WARN, 212 "n2rng: n2rng_collect_bits returns 0x%x", rv); 213 } else { 214 n2rng_renyi_entropy(buffer, LOG2_DATA_WORDS, metricp); 215 } 216 217 contig_mem_free(buffer, bufsize); 218 219 return (rv); 220 } 221 222 223 /* 224 * Fills in table with the performance of each oscillator at each 225 * bias setting. A particular datum goes in table[osc][bias]. 226 */ 227 int 228 collect_rng_perf(n2rng_t *n2rng, n2rng_osc_perf_table_t ptable) 229 { 230 int bias; 231 int osc; 232 n2rng_setup_t rngstate; 233 int rv; 234 235 rngstate.ctlwds[0].word = 0; 236 rngstate.ctlwds[0].fields.rnc_anlg_sel = N2RNG_NOANALOGOUT; 237 rngstate.ctlwds[1] = rngstate.ctlwds[0]; 238 rngstate.ctlwds[2] = rngstate.ctlwds[0]; 239 rngstate.ctlwds[3] = rngstate.ctlwds[0]; 240 241 for (osc = 0; osc < N2RNG_NOSC; osc++) { 242 rngstate.ctlwds[3].fields.rnc_selbits = 1 << osc; 243 for (bias = 0; bias < N2RNG_NBIASES; bias++) { 244 rngstate.ctlwds[3].fields.rnc_vcoctl = bias; 245 rv = n2rng_collect_metrics(n2rng, &rngstate, 246 &n2rng->n_preferred_config, 247 n2rng->n_rng_state, 248 &(ptable[osc][bias])); 249 if (rv) { 250 return (rv); 251 } 252 } 253 } 254 255 return (rv); 256 } 257 258 259 260 /* 261 * The following 2 functions test the performance of each noise cell 262 * and select the bias settings. They implement the following 263 * policies: 264 * 265 * 1. No two cells may be set to the same bias. (Cells with the same bias, 266 * which controls frequency, may beat together, with long 267 * runs of no entropy as a pair when they are nearly synchronized.) 268 * 2. The entropy of each cell is determined (for now) by the Renyi H2 269 * entropy of a collection of samples of raw bits. 270 * 3. The selected configuration is the one that has the largest total 271 * entropy, computed as stated above. 272 * 4. The delay is hard coded. 273 */ 274 275 276 /* 277 * Finds the preferred configuration from perf data. Sets the 278 * preferred configuration in the n2rng structure. 279 */ 280 int 281 n2rng_noise_gen_preferred(n2rng_t *n2rng) 282 { 283 int rv; 284 int rventropy = 0; /* EIO if entropy is too low */ 285 int b0, b1, b2; 286 int osc; 287 int bset; 288 n2rng_osc_perf_t *candidates[N2RNG_NOSC]; 289 uint64_t bestcellentropy[N2RNG_NOSC] = {0}; 290 uint64_t bestentropy = 0; 291 n2rng_ctl_t rng_ctl = {0}; 292 int i; 293 294 rv = collect_rng_perf(n2rng, n2rng->n_perftable); 295 if (rv) { 296 return (rv); 297 } 298 299 /* 300 * bset is the bias setting of all 3 oscillators packed into a 301 * word, 2 bits for each: b2:b1:b0. First we set up an 302 * arbitrary assignement, because in an earlier version of 303 * this code, there were cases where the assignment would 304 * never happen. Also, that way we don't need to prove 305 * assignment to prove we never have uninitalized variables, 306 * and hence it might avoid lint warnings. 307 * 308 * This block of code picks the "best" setting of the biases, 309 * where "best" is defined by the rules in the big comment 310 * block above. 311 * 312 * There are only 24 possible combinations such that no two 313 * oscillators get the same bias. We just do a brute force 314 * exhaustive search of the entire space. 315 */ 316 bset = ENCODEBIAS(2, 2) | ENCODEBIAS(1, 1) | ENCODEBIAS(0, 0); 317 for (b0 = 0; b0 < N2RNG_NBIASES; b0++) { 318 candidates[0] = &n2rng->n_perftable[0][b0]; 319 for (b1 = 0; b1 < N2RNG_NBIASES; b1++) { 320 if (b0 == b1) continue; 321 candidates[1] = &n2rng->n_perftable[1][b1]; 322 for (b2 = 0; b2 < N2RNG_NBIASES; b2++) { 323 uint64_t totalentropy = 0; 324 325 if (b0 == b2 || b1 == b2) continue; 326 candidates[2] = &n2rng->n_perftable[2][b2]; 327 for (i = 0; i < N2RNG_NOSC; i++) { 328 totalentropy += candidates[i]->H2; 329 } 330 if (totalentropy > bestentropy) { 331 bestentropy = totalentropy; 332 bset = ENCODEBIAS(0, b0) | 333 ENCODEBIAS(1, b1) | 334 ENCODEBIAS(2, b2); 335 for (i = 0; i < N2RNG_NOSC; i++) { 336 bestcellentropy[i] = 337 candidates[i]->H2; 338 } 339 340 } 341 342 } 343 } 344 } 345 346 if (bestentropy < ENTROPY_PASS_VALUE) { 347 cmn_err(CE_WARN, 348 "n2rng: RNG hardware producing insufficient " 349 "entropy (producing %ld, need %lld)", 350 bestentropy, ENTROPY_PASS_VALUE); 351 rventropy = EIO; 352 } 353 354 /* 355 * Set up fields of control words that will be the same for all 356 * osciallators and for final value that selects all 357 * oscillators. 358 */ 359 rng_ctl.fields.rnc_cnt = RNG_DEFAULT_ACCUMULATE_CYCLES; 360 rng_ctl.fields.rnc_mode = 1; /* set normal mode */ 361 rng_ctl.fields.rnc_anlg_sel = N2RNG_NOANALOGOUT; 362 363 364 /* 365 * Now set the oscillator biases. 366 */ 367 for (osc = 0; osc < N2RNG_NOSC; osc++) { 368 rng_ctl.fields.rnc_selbits = 1 << osc; 369 rng_ctl.fields.rnc_vcoctl = EXTRACTBIAS(bset, osc); 370 n2rng->n_preferred_config.ctlwds[osc] = rng_ctl; 371 } 372 373 rng_ctl.fields.rnc_cnt = RNG_DEFAULT_ACCUMULATE_CYCLES; 374 rng_ctl.fields.rnc_vcoctl = 0; 375 rng_ctl.fields.rnc_selbits = 0x7; 376 n2rng->n_preferred_config.ctlwds[3] = rng_ctl; 377 378 /* 379 * Log the entropy and bias setting for the admin and security 380 * auditors. 381 */ 382 if (rventropy == 0) { 383 cmn_err(CE_NOTE, 384 "!n2rng: RNG passes, " 385 "cell 0 bias %d: %ld, " 386 "cell 1 bias %d: %ld, " 387 "cell 2 bias %d: %ld", 388 EXTRACTBIAS(bset, 0), 389 (uint64_t)(bestcellentropy[0] / ENTDIVISOR), 390 EXTRACTBIAS(bset, 1), 391 (uint64_t)(bestcellentropy[1] / ENTDIVISOR), 392 EXTRACTBIAS(bset, 2), 393 (uint64_t)(bestcellentropy[2] / ENTDIVISOR)); 394 395 } 396 397 return (rv ? rv : rventropy); 398 } 399 400 401 402 /* 403 * Do a logic test, then find and set the best bias confuration 404 * (failing if insufficient entropy is generated, then set state to 405 * configured. 406 */ 407 int 408 n2rng_do_health_check(n2rng_t *n2rng) 409 { 410 int rv; 411 int hverr; 412 413 /* Take control of RNG */ 414 do { 415 hverr = hv_rng_get_diag_control(); 416 rv = n2rng_herr2kerr(hverr); 417 } while (hverr == H_EWOULDBLOCK); 418 419 if (hverr) 420 return (rv); 421 422 rv = n2rng_logic_test(n2rng); 423 if (rv) { 424 return (rv); 425 } 426 427 rv = n2rng_noise_gen_preferred(n2rng); 428 if (rv) { 429 return (rv); 430 } 431 432 /* Push the selected config into HW */ 433 rv = n2rng_collect_diag_bits(n2rng, NULL, NULL, 0, 434 &n2rng->n_preferred_config, CTL_STATE_CONFIGURED); 435 if (rv) { 436 return (rv); 437 } 438 439 n2rng->n_rng_state = CTL_STATE_CONFIGURED; 440 441 return (rv); 442 } 443