1fec509a0Sgm89044 /* 2fec509a0Sgm89044 * CDDL HEADER START 3fec509a0Sgm89044 * 4fec509a0Sgm89044 * The contents of this file are subject to the terms of the 5fec509a0Sgm89044 * Common Development and Distribution License (the "License"). 6fec509a0Sgm89044 * You may not use this file except in compliance with the License. 7fec509a0Sgm89044 * 8fec509a0Sgm89044 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fec509a0Sgm89044 * or http://www.opensolaris.org/os/licensing. 10fec509a0Sgm89044 * See the License for the specific language governing permissions 11fec509a0Sgm89044 * and limitations under the License. 12fec509a0Sgm89044 * 13fec509a0Sgm89044 * When distributing Covered Code, include this CDDL HEADER in each 14fec509a0Sgm89044 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fec509a0Sgm89044 * If applicable, add the following below this CDDL HEADER, with the 16fec509a0Sgm89044 * fields enclosed by brackets "[]" replaced with your own identifying 17fec509a0Sgm89044 * information: Portions Copyright [yyyy] [name of copyright owner] 18fec509a0Sgm89044 * 19fec509a0Sgm89044 * CDDL HEADER END 20fec509a0Sgm89044 */ 21fec509a0Sgm89044 /* 22*32e0ab73SMisaki Miyashita * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23fec509a0Sgm89044 */ 24fec509a0Sgm89044 25fec509a0Sgm89044 #include <sys/types.h> 26fec509a0Sgm89044 #include <sys/sysmacros.h> 27fec509a0Sgm89044 #include <sys/modctl.h> 28fec509a0Sgm89044 #include <sys/conf.h> 29fec509a0Sgm89044 #include <sys/devops.h> 30fec509a0Sgm89044 #include <sys/cmn_err.h> 31fec509a0Sgm89044 #include <sys/kmem.h> 32fec509a0Sgm89044 #include <sys/stat.h> 33fec509a0Sgm89044 #include <sys/open.h> 34fec509a0Sgm89044 #include <sys/file.h> 35fec509a0Sgm89044 #include <sys/cpuvar.h> 36fec509a0Sgm89044 #include <sys/disp.h> 37fec509a0Sgm89044 #include <sys/hsvc.h> 38fec509a0Sgm89044 #include <sys/machsystm.h> 39fec509a0Sgm89044 #include <sys/ksynch.h> 40fec509a0Sgm89044 #include <sys/hypervisor_api.h> 41fec509a0Sgm89044 #include <sys/n2rng.h> 42fec509a0Sgm89044 #include <sys/sha1.h> 43fec509a0Sgm89044 #include <sys/ddi.h> /* near end to get min and max macros right */ 44fec509a0Sgm89044 #include <sys/sunddi.h> 45fe54a78eSHai-May Chao #include <rng/fips_random.h> 46fec509a0Sgm89044 47fec509a0Sgm89044 /* n must be a power of 2 */ 48fec509a0Sgm89044 #define ROUNDUP(k, n) (((k) + (n) - 1) & ~((n) - 1)) 49fec509a0Sgm89044 50fec509a0Sgm89044 /* 51fec509a0Sgm89044 * Policy. ENTROPY_STARVATION is the maximum number of calls each 52fec509a0Sgm89044 * FIPS instance will accept without successfully getting more 53fec509a0Sgm89044 * entropy. It needs to be large enough to allow RNG operations to 54fec509a0Sgm89044 * not stall because of health checks, etc. But we don't want it too 55fec509a0Sgm89044 * large. FIPS 186-2 change 1 (5 October 2001) states that no more 56fec509a0Sgm89044 * that 2,000,000 DSA signatures (done using this algorithm) should be 57fec509a0Sgm89044 * done without reseeding. We make sure we add 64 bits of entropy at 58fec509a0Sgm89044 * most every 10000 operations, hence we will have stirred in 160 bits 59fec509a0Sgm89044 * of entropy at most once every 30000 operations. Normally, we stir 60fec509a0Sgm89044 * in 64 bits of entropy for every number generated. 61fec509a0Sgm89044 */ 62fec509a0Sgm89044 #define ENTROPY_STARVATION 10000ULL 63fec509a0Sgm89044 64fec509a0Sgm89044 65fec509a0Sgm89044 int 66fec509a0Sgm89044 fips_random(n2rng_t *n2rng, uint8_t *out, size_t nbytes) 67fec509a0Sgm89044 { 68fec509a0Sgm89044 int i; 69fec509a0Sgm89044 fipsrandomstruct_t *frsp; 70741c280dStwelke int rv; 71fec509a0Sgm89044 union { 72fec509a0Sgm89044 uint32_t as32[SHA1WORDS]; 73fec509a0Sgm89044 uint64_t as64[ROUNDUP(SHA1WORDS, 2) >> 1]; 74fec509a0Sgm89044 } entropy = {0}; 75fec509a0Sgm89044 uint32_t tempout[SHA1WORDS]; 76fec509a0Sgm89044 77fec509a0Sgm89044 78fec509a0Sgm89044 for (i = 0; i < nbytes; i += SHA1BYTES) { 79741c280dStwelke frsp = &n2rng->n_frs.fipsarray[ 80741c280dStwelke atomic_inc_32_nv(&n2rng->n_frs.fips_round_robin_j) % 81741c280dStwelke N2RNG_FIPS_INSTANCES]; 82fec509a0Sgm89044 /* 83fec509a0Sgm89044 * Since in the new scheme of things, the RNG latency 84fec509a0Sgm89044 * will be high on reads after the first, we get just 85741c280dStwelke * one word of entropy per call. 86fec509a0Sgm89044 */ 87741c280dStwelke if ((rv = n2rng_getentropy(n2rng, (void *)&entropy.as64[1], 88741c280dStwelke sizeof (uint64_t))) != 0) { 89741c280dStwelke 90741c280dStwelke /* 91741c280dStwelke * If all rngs have failed, dispatch task to unregister 92741c280dStwelke * from kcf and put the driver in an error state. If 93741c280dStwelke * recoverable errors persist, a configuration retry 94741c280dStwelke * will be initiated. 95741c280dStwelke */ 96741c280dStwelke if (rv == EPERM) { 97741c280dStwelke n2rng_failure(n2rng); 98741c280dStwelke return (EIO); 99741c280dStwelke } 100741c280dStwelke /* Failure with possible recovery */ 101fec509a0Sgm89044 entropy.as64[1] = 0; 102fec509a0Sgm89044 } 103fec509a0Sgm89044 104fec509a0Sgm89044 /* 105fec509a0Sgm89044 * The idea here is that a Niagara2 chip is highly 106fec509a0Sgm89044 * parallel, with many strands. If we have just one 107fec509a0Sgm89044 * instance of the FIPS data, then only one FIPS 108fec509a0Sgm89044 * computation can happen at a time, serializeing all 109fec509a0Sgm89044 * the RNG stuff. So we make N2RNG_FIPS_INSTANCES, 110fec509a0Sgm89044 * and use them round-robin, with the counter being 111fec509a0Sgm89044 * n2rng->n_frs.fips_round_robin_j. We increment the 112fec509a0Sgm89044 * counter with an atomic op, avoiding having to have 113fec509a0Sgm89044 * a global muxtex. The atomic ops are also 114fec509a0Sgm89044 * significantly faster than mutexes. The mutex is 115fec509a0Sgm89044 * put inside the loop, otherwise one thread reading 116fec509a0Sgm89044 * many blocks could stall all other strands. 117fec509a0Sgm89044 */ 118fec509a0Sgm89044 frsp = &n2rng->n_frs.fipsarray[ 119fec509a0Sgm89044 atomic_inc_32_nv(&n2rng->n_frs.fips_round_robin_j) % 120fec509a0Sgm89044 N2RNG_FIPS_INSTANCES]; 121fec509a0Sgm89044 122fec509a0Sgm89044 mutex_enter(&frsp->mtx); 123fec509a0Sgm89044 124fec509a0Sgm89044 if (entropy.as64[1] == 0) { 125fec509a0Sgm89044 /* 126fec509a0Sgm89044 * If we did not get any entropy, entropyword 127fec509a0Sgm89044 * is zero. We get a false positive with 128fec509a0Sgm89044 * probablitity 2^-64. It's not worth a few 129fec509a0Sgm89044 * extra stores and tests eliminate the false 130fec509a0Sgm89044 * positive. 131fec509a0Sgm89044 */ 132fec509a0Sgm89044 if (++frsp->entropyhunger > ENTROPY_STARVATION) { 133fec509a0Sgm89044 mutex_exit(&frsp->mtx); 134741c280dStwelke n2rng_unconfigured(n2rng); 135fec509a0Sgm89044 return (EIO); 136fec509a0Sgm89044 } 137fec509a0Sgm89044 } else { 138fec509a0Sgm89044 frsp->entropyhunger = 0; 139fec509a0Sgm89044 } 140fec509a0Sgm89044 141fec509a0Sgm89044 /* nbytes - i is bytes to go */ 142fe54a78eSHai-May Chao fips_random_inner(frsp->XKEY, tempout, entropy.as32); 143*32e0ab73SMisaki Miyashita 144fec509a0Sgm89044 bcopy(tempout, &out[i], min(nbytes - i, SHA1BYTES)); 145fec509a0Sgm89044 146fec509a0Sgm89044 mutex_exit(&frsp->mtx); 147fec509a0Sgm89044 } 148fec509a0Sgm89044 149fec509a0Sgm89044 /* Zeroize sensitive information */ 150fec509a0Sgm89044 151fec509a0Sgm89044 entropy.as64[1] = 0; 152fec509a0Sgm89044 bzero(tempout, SHA1BYTES); 153fec509a0Sgm89044 154fec509a0Sgm89044 return (0); 155fec509a0Sgm89044 } 156fec509a0Sgm89044 157fec509a0Sgm89044 /* 158fec509a0Sgm89044 * Initializes one FIPS RNG instance. Must be called once for each 159fec509a0Sgm89044 * instance. 160fec509a0Sgm89044 */ 161fec509a0Sgm89044 int 162fec509a0Sgm89044 n2rng_fips_random_init(n2rng_t *n2rng, fipsrandomstruct_t *frsp) 163fec509a0Sgm89044 { 164fec509a0Sgm89044 /* 165fec509a0Sgm89044 * All FIPS-approved algorithms will operate as cryptograpic 166fec509a0Sgm89044 * quality PRNGs even if there is no entropy source. (In 167fec509a0Sgm89044 * fact, this the only one that accepts entropy on the fly.) 168fec509a0Sgm89044 * One motivation for this is that they system keeps on 169fec509a0Sgm89044 * delivering cryptographic quality random numbers, even if 170fec509a0Sgm89044 * the entropy source fails. 171fec509a0Sgm89044 */ 172fec509a0Sgm89044 173fec509a0Sgm89044 int rv; 174*32e0ab73SMisaki Miyashita static uint32_t FIPS_RNG_NO_USER_INPUT[] = {0, 0, 0, 0, 0}; 175fec509a0Sgm89044 176fec509a0Sgm89044 rv = n2rng_getentropy(n2rng, (void *)frsp->XKEY, ROUNDUP(SHA1BYTES, 8)); 177fec509a0Sgm89044 if (rv) { 178fec509a0Sgm89044 return (rv); 179fec509a0Sgm89044 } 180741c280dStwelke frsp->entropyhunger = 0; 181fec509a0Sgm89044 mutex_init(&frsp->mtx, NULL, MUTEX_DRIVER, NULL); 182fec509a0Sgm89044 183*32e0ab73SMisaki Miyashita /* compute the first (compare only) random value */ 184*32e0ab73SMisaki Miyashita fips_random_inner(frsp->XKEY, frsp->x_jminus1, FIPS_RNG_NO_USER_INPUT); 185*32e0ab73SMisaki Miyashita 186fec509a0Sgm89044 return (0); 187fec509a0Sgm89044 } 188fec509a0Sgm89044 189fec509a0Sgm89044 void 190fec509a0Sgm89044 n2rng_fips_random_fini(fipsrandomstruct_t *frsp) 191fec509a0Sgm89044 { 192fec509a0Sgm89044 mutex_destroy(&frsp->mtx); 193fec509a0Sgm89044 /* 194fec509a0Sgm89044 * Zeroise fips data. Not really necessary, since the 195fec509a0Sgm89044 * algorithm has backtracking resistance, but do it anyway. 196fec509a0Sgm89044 */ 197fec509a0Sgm89044 bzero(frsp, sizeof (fipsrandomstruct_t)); 198fec509a0Sgm89044 } 199