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