xref: /titanic_53/usr/src/uts/sun4v/sys/n2rng.h (revision 4496171313bed39e96f21bc2f9faf2868e267ae3)
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