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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_N2RNG_H 27 #define _SYS_N2RNG_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* skip following stuff when included in n2rng_hcall.s */ 32 #ifndef _ASM 33 #include <sys/types.h> 34 #include <sys/mutex.h> 35 #include <sys/ksynch.h> 36 #include <sys/sunddi.h> 37 #include <sys/param.h> 38 #include <sys/crypto/common.h> 39 #include <sys/crypto/spi.h> 40 41 #endif /* !_ASM */ 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 /* 48 * RNG HV API version definitions. 49 */ 50 #define RNG_MAJOR_VER 1 51 #define RNG_MINOR_VER 0 52 53 #define HV_RNG_GET_DIAG_CONTROL 0x130 54 #define HV_RNG_CTL_READ 0x131 55 #define HV_RNG_CTL_WRITE 0x132 56 #define HV_RNG_DATA_READ_DIAG 0x133 57 #define HV_RNG_DATA_READ 0x134 58 59 #define CTL_STATE_UNCONFIGURED 0 60 #define CTL_STATE_CONFIGURED 1 61 #define CTL_STATE_HEALTHCHECK 2 62 #define CTL_STATE_ERROR 3 63 64 #define NRNGCTL 4 65 #define N2RNG_MAX_READ (128 * 1024) /* 128K bytes */ 66 67 #define DRIVER "n2rng" 68 #define N2RNG_MANUFACTURER_ID "SUNWn2rng" 69 70 71 #ifndef _ASM 72 73 typedef union n2rngctl { 74 uint64_t word; 75 struct { 76 uint64_t rnc_res : 39; 77 uint64_t rnc_cnt : 16; 78 uint64_t rnc_bypass : 1; 79 uint64_t rnc_vcoctl : 2; 80 uint64_t rnc_anlg_sel : 2; 81 uint64_t rnc_mode : 1; 82 uint64_t rnc_selbits : 3; 83 } fields; 84 } n2rng_ctl_t; 85 86 typedef struct { 87 n2rng_ctl_t ctlwds[NRNGCTL]; 88 } n2rng_setup_t; 89 90 #if defined(_KERNEL) 91 92 /* 93 * Our contiguous memory alignment requirement is 94 * only for 8 bytes, however contig mem allocation 95 * routines requirement minimum of 64. 96 */ 97 #define CONTIG_ALIGNMENT 64 98 /* 99 * Returns 1 only if the address range of a variable of type type at 100 * ptr falls entirely on one page. Based on page size of 4K. May 101 * give some false negatives on larger page sizes. 102 */ 103 #define CONTIGUOUS(ptr, type) \ 104 (((((uint64_t)(ptr)) ^ ((uint64_t)(ptr) + sizeof (type) -1)) \ 105 & PAGEMASK) == 0) 106 107 /* 108 * The RNG hardware can send certain internal analog signals to an 109 * external pin on the chip. Setting the rnc_anlg_sel bit to 110 * N2RNG_NOANALOGOUT deselects all analog signals (perhaps selects 111 * ground). Choosing any other value would aid an attacker with 112 * physical access to the chip. 113 */ 114 #define N2RNG_NOANALOGOUT 0x2 115 116 /* 117 * There can only be N2_RNG_FIPS_INSTANCES concurrent RNG requsts from 118 * the framework. Making this value large helps benchmarks. It 119 * should probably come from a conf file, but for now it is hard 120 * coded. The code computes i % N2RNG_FIPS_INSTANCES, which is more 121 * efficient when N2RNG_FIPS_INSTANCES is a power of 2. 122 */ 123 #define N2RNG_FIPS_INSTANCES 8 124 125 typedef struct fipsrandomstruct fipsrandomstruct_t; 126 struct fipsrandomstruct { 127 kmutex_t mtx; 128 uint64_t entropyhunger; /* RNGs generated with no entropy */ 129 uint32_t XKEY[6]; /* one extra word for getentropy */ 130 }; 131 132 typedef struct { 133 /* 134 * volatile, since it is not protected by a mutex. (That is 135 * okay since it is operated on and accessed via atomic ops.) 136 */ 137 volatile unsigned int fips_round_robin_j; 138 fipsrandomstruct_t fipsarray[N2RNG_FIPS_INSTANCES]; 139 } fips_ensemble_t; 140 141 #define N2RNG_FAILED 0x1 /* for n_flags; used by kstat */ 142 143 #define DS_RNGBYTES 0 144 #define DS_RNGJOBS 1 145 #define DS_RNGHEALTHCHECKS 2 146 #define DS_MAX 3 147 148 #define N2RNG_NOSC 3 149 #define N2RNG_BIASBITS 2 150 #define N2RNG_NBIASES (1 << N2RNG_BIASBITS) 151 #define N2RNG_CTLOPS (N2RNG_OSC + 1) 152 153 typedef struct { 154 uint64_t numvals; 155 uint64_t H1; /* in bits per bit << LOG_VAL_SCALE */ 156 uint64_t H2; 157 uint64_t Hinf; 158 } n2rng_osc_perf_t; 159 160 typedef n2rng_osc_perf_t n2rng_osc_perf_table_t[N2RNG_NOSC][N2RNG_NBIASES]; 161 162 163 typedef struct n2rng { 164 kmutex_t n_lock; 165 dev_info_t *n_dip; 166 minor_t n_minor; 167 unsigned n_flags; /* dev state flags */ 168 kstat_t *n_ksp; 169 uint64_t n_stats[DS_MAX]; 170 crypto_kcf_provider_handle_t n_prov; 171 fips_ensemble_t n_frs; 172 n2rng_osc_perf_table_t n_perftable; 173 n2rng_setup_t n_preferred_config; 174 kmutex_t n_health_check_mutex; 175 time_t n_last_health_time; 176 uint64_t n_rng_state; /* as last known in this drvr. */ 177 uint64_t n_sticks_per_usec; 178 uint64_t n_anlg_settle_cycles; 179 } n2rng_t; 180 181 182 typedef struct n2rng_stat n2rng_stat_t; 183 struct n2rng_stat { 184 kstat_named_t ns_status; 185 kstat_named_t ns_algs[DS_MAX]; 186 }; 187 188 #define RNG_MODE_NORMAL 1 189 #define RNG_MODE_DIAGNOSTIC 0 190 191 #define RNG_CTL_SETTLE_NS 2000000 /* nanoseconds */ 192 #define RNG_DIAG_CHUNK_SIZE (N2RNG_MAX_READ / 8) /* as words */ 193 #define RNG_MAX_DATA_READ_ATTEMPTS 100 194 #define RNG_DEFAULT_ACCUMULATE_CYCLES 4000 195 #define RNG_RETRY_HLCHK_USECS 100000 /* retry every .1 seconds */ 196 197 #define LOG_ARG_SCALE 49 198 #define LOG_VAL_SCALE 32 199 200 201 void n2rng_sort(uint64_t *data, int log2_size); 202 int n2rng_noise_gen_preferred(n2rng_t *n2rng); 203 int n2rng_check_set(n2rng_t *n2rng); 204 int n2rng_collect_diag_bits(n2rng_t *n2rng, n2rng_setup_t *collect_setupp, 205 void *buffer, int numbytes, n2rng_setup_t *exit_setupp, 206 uint64_t exitstate); 207 int n2rng_getentropy(n2rng_t *n2rng, void *buffer, size_t size); 208 int n2rng_fips_random_init(n2rng_t *n2rng, fipsrandomstruct_t *frsp); 209 void n2rng_fips_random_fini(fipsrandomstruct_t *frsp); 210 int n2rng_do_health_check(n2rng_t *n2rng); 211 void n2rng_renyi_entropy(uint64_t *buffer, int log2samples, 212 n2rng_osc_perf_t *metricp); 213 214 215 216 217 #if defined(DEBUG) 218 219 #define DWARN 0x00000001 220 #define DMA_ARGS 0x00000002 221 #define DMA_LDST 0x00000004 222 #define DNCS_QTAIL 0x00000008 223 #define DATTACH 0x00000010 224 #define DMOD 0x00000040 /* _init/_fini/_info/attach/detach */ 225 #define DENTRY 0x00000080 /* crypto routine entry/exit points */ 226 #define DCHATTY 0x00000100 227 #define DALL 0xFFFFFFFF 228 229 #define DBG0 n2rng_dprintf 230 #define DBG1 n2rng_dprintf 231 #define DBG2 n2rng_dprintf 232 #define DBG3 n2rng_dprintf 233 #define DBG4 n2rng_dprintf 234 #define DBG5 n2rng_dprintf 235 #define DBG6 n2rng_dprintf 236 #define DBGCALL(flag, func) { if (n2rng_dflagset(flag)) (void) func; } 237 238 void n2rng_dprintf(n2rng_t *, int, const char *, ...); 239 void n2rng_dumphex(void *, int); 240 int n2rng_dflagset(int); 241 242 #else /* !defined(DEBUG) */ 243 244 #define DBG0(vca, lvl, fmt) 245 #define DBG1(vca, lvl, fmt, arg1) 246 #define DBG2(vca, lvl, fmt, arg1, arg2) 247 #define DBG3(vca, lvl, fmt, arg1, arg2, arg3) 248 #define DBG4(vca, lvl, fmt, arg1, arg2, arg3, arg4) 249 #define DBG5(vca, lvl, fmt, arg1, arg2, arg3, arg4, arg5) 250 #define DBG6(vca, lvl, fmt, arg1, arg2, arg3, arg4, arg5, arg6) 251 #define DBGCALL(flag, func) 252 253 #endif /* !defined(DEBUG) */ 254 255 /* 256 * n2rng_debug.c 257 */ 258 void n2rng_error(n2rng_t *, const char *, ...); 259 void n2rng_diperror(dev_info_t *, const char *, ...); 260 void n2rng_dipverror(dev_info_t *, const char *, va_list); 261 262 uint64_t hv_rng_get_diag_control(void); 263 uint64_t hv_rng_read_ctl(uint64_t ctlregs_pa, uint64_t *state, 264 uint64_t *tdelta); 265 uint64_t hv_rng_ctl_write(uint64_t ctlregs_pa, 266 uint64_t newstate, uint64_t wtimeout, uint64_t *tdelta); 267 uint64_t hv_rng_data_read_diag(uint64_t data_pa, 268 size_t datalen, uint64_t *tdelta); 269 uint64_t hv_rng_data_read(uint64_t data_pa, uint64_t *tdelta); 270 271 #endif /* _KERNEL */ 272 #endif /* !_ASM */ 273 274 #ifdef __cplusplus 275 } 276 #endif 277 278 #endif /* _SYS_N2RNG_H */ 279