xref: /illumos-gate/usr/src/uts/sun4v/sys/n2rng.h (revision dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9)
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 2009 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 /* skip following stuff when included in n2rng_hcall.s */
30 #ifndef _ASM
31 #include <sys/types.h>
32 #include <sys/mutex.h>
33 #include <sys/ksynch.h>
34 #include <sys/sunddi.h>
35 #include <sys/param.h>
36 #include <sys/crypto/common.h>
37 #include <sys/crypto/spi.h>
38 #include <sys/mdesc.h>
39 
40 #endif /* !_ASM */
41 
42 #ifdef	__cplusplus
43 extern "C" {
44 #endif
45 
46 #define	HV_RNG_GET_DIAG_CONTROL	0x130
47 #define	HV_RNG_CTL_READ		0x131
48 #define	HV_RNG_CTL_WRITE	0x132
49 #define	HV_RNG_DATA_READ_DIAG	0x133
50 #define	HV_RNG_DATA_READ	0x134
51 
52 #define	CTL_STATE_UNCONFIGURED	0
53 #define	CTL_STATE_CONFIGURED	1
54 #define	CTL_STATE_HEALTHCHECK	2
55 #define	CTL_STATE_ERROR		3
56 
57 #define	NRNGCTL			4
58 #define	N2RNG_MAX_READ		(128 * 1024)	/* 128K bytes */
59 
60 #define	DRIVER			"n2rng"
61 #define	N2RNG_MANUFACTURER_ID	"SUNWn2rng"
62 
63 #define	N2RNG_BINDNAME_N2	"SUNW,n2-rng"
64 #define	N2RNG_BINDNAME_VF	"SUNW,vf-rng"
65 
66 #define	N2RNG_MAX_RNGS		4
67 #define	N2RNG_INVALID_ID	(-1)
68 
69 #ifndef _ASM
70 
71 typedef enum {
72 	N2RNG_CPU_UNKNOWN,
73 	N2RNG_CPU_N2,
74 	N2RNG_CPU_VF
75 } n2rng_binding_t;
76 
77 typedef union n2rngctl {
78 	uint64_t	word;
79 	struct {
80 		uint64_t rnc_res : 39;
81 		uint64_t rnc_cnt : 16;
82 		uint64_t rnc_bypass : 1;
83 		uint64_t rnc_vcoctl : 2;
84 		uint64_t rnc_anlg_sel : 2;
85 		uint64_t rnc_mode : 1;
86 		uint64_t rnc_selbits : 3;
87 	} fields;
88 } n2rng_ctl_t;
89 
90 typedef struct {
91 	n2rng_ctl_t ctlwds[NRNGCTL];
92 } n2rng_setup_t;
93 
94 #if defined(_KERNEL)
95 
96 /*
97  * Our contiguous memory alignment requirement is
98  * only for 8 bytes, however contig mem allocation
99  * routines requirement minimum of 64.
100  */
101 #define	CONTIG_ALIGNMENT	64
102 
103 /*
104  * Returns 1 only if the address range of a variable of type type at
105  * ptr falls entirely on one page.  Based on page size of 4K.  May
106  * give some false negatives on larger page sizes.
107  */
108 #define	CONTIGUOUS(ptr, type)	\
109 	(((((uint64_t)(ptr)) ^ ((uint64_t)(ptr) + sizeof (type) -1))	\
110 	& PAGEMASK) == 0)
111 
112 /*
113  * The RNG hardware can send certain internal analog signals to an
114  * external pin on the chip.  Setting the rnc_anlg_sel bit to
115  * N2RNG_NOANALOGOUT deselects all analog signals (perhaps selects
116  * ground).  Choosing any other value would aid an attacker with
117  * physical access to the chip.
118  */
119 #define	N2RNG_NOANALOGOUT	0x2
120 
121 /*
122  * There can only be N2_RNG_FIPS_INSTANCES concurrent RNG requsts from
123  * the framework.  Making this value large helps benchmarks.  It
124  * should probably come from a conf file, but for now it is hard
125  * coded.  The code computes i % N2RNG_FIPS_INSTANCES, which is more
126  * efficient when N2RNG_FIPS_INSTANCES is a power of 2.
127  */
128 #define	N2RNG_FIPS_INSTANCES 8
129 
130 typedef struct fipsrandomstruct fipsrandomstruct_t;
131 struct fipsrandomstruct {
132 	kmutex_t	mtx;
133 	uint64_t	entropyhunger;  /* RNGs generated with no entropy */
134 	uint32_t	XKEY[6]; /* one extra word for getentropy */
135 };
136 
137 typedef struct {
138 	/*
139 	 * volatile, since it is not protected by a mutex.  (That is
140 	 * okay since it is operated on and accessed via atomic ops.)
141 	 */
142 	volatile unsigned int	fips_round_robin_j;
143 	fipsrandomstruct_t	fipsarray[N2RNG_FIPS_INSTANCES];
144 } fips_ensemble_t;
145 
146 /*
147  * Device flags (n2rng_t.n_flags)
148  */
149 #define	N2RNG_CONTROL		0x00000001
150 #define	N2RNG_FAILED		0x00000002
151 #define	N2RNG_CONFIGURED	0x00000004
152 #define	N2RNG_INITIALIZED	0x00000008
153 #define	N2RNG_REGISTERED	0x00000010
154 
155 #define	n2rng_setcontrol(n2rng)		((n2rng)->n_flags |= N2RNG_CONTROL)
156 #define	n2rng_clrcontrol(n2rng)		((n2rng)->n_flags &= ~N2RNG_CONTROL)
157 #define	n2rng_iscontrol(n2rng)		((n2rng)->n_flags & N2RNG_CONTROL)
158 
159 #define	n2rng_setfailed(n2rng)		((n2rng)->n_flags |= N2RNG_FAILED)
160 #define	n2rng_clrfailed(n2rng)		((n2rng)->n_flags &= ~N2RNG_FAILED)
161 #define	n2rng_isfailed(n2rng)		((n2rng)->n_flags & N2RNG_FAILED)
162 
163 #define	n2rng_setconfigured(n2rng)	((n2rng)->n_flags |= N2RNG_CONFIGURED)
164 #define	n2rng_clrconfigured(n2rng)	((n2rng)->n_flags &= ~N2RNG_CONFIGURED)
165 #define	n2rng_isconfigured(n2rng)	((n2rng)->n_flags & N2RNG_CONFIGURED)
166 
167 #define	n2rng_setinitialized(n2rng)	((n2rng)->n_flags |= N2RNG_INITIALIZED)
168 #define	n2rng_clrinitialized(n2rng)	((n2rng)->n_flags &= ~N2RNG_INITIALIZED)
169 #define	n2rng_isinitialized(n2rng)	((n2rng)->n_flags & N2RNG_INITIALIZED)
170 
171 #define	n2rng_setregistered(n2rng)	((n2rng)->n_flags |= N2RNG_REGISTERED)
172 #define	n2rng_clrregistered(n2rng)	((n2rng)->n_flags &= ~N2RNG_REGISTERED)
173 #define	n2rng_isregistered(n2rng)	((n2rng)->n_flags & N2RNG_REGISTERED)
174 
175 #define	DS_RNGBYTES		0
176 #define	DS_RNGJOBS		1
177 #define	DS_RNGHEALTHCHECKS	2
178 #define	DS_MAX			3
179 
180 #define	N2RNG_NOSC		3
181 #define	N2RNG_BIASBITS		2
182 #define	N2RNG_NBIASES		(1 << N2RNG_BIASBITS)
183 #define	N2RNG_CTLOPS		(N2RNG_OSC + 1)
184 
185 #define	N2RNG_PROP_NUM_UNITS	"rng-#units"
186 #define	SECOND			1000000		/* micro seconds */
187 
188 typedef struct {
189 	uint64_t	numvals;
190 	uint64_t	H1;	/* in bits per bit << LOG_VAL_SCALE */
191 	uint64_t	H2;
192 	uint64_t	Hinf;
193 } n2rng_osc_perf_t;
194 
195 typedef n2rng_osc_perf_t n2rng_osc_perf_table_t[N2RNG_NOSC][N2RNG_NBIASES];
196 
197 typedef struct {
198 	uint64_t	bias;
199 	uint64_t	entropy;
200 } n2rng_bias_info_t;
201 
202 typedef struct {
203 	n2rng_bias_info_t	n_bias_info[N2RNG_NOSC];
204 	n2rng_osc_perf_table_t	n_perftable;
205 	n2rng_setup_t		n_preferred_config;
206 	uint64_t		n_rng_state; /* as last known in this drvr. */
207 } rng_entry_t;
208 
209 typedef struct {
210 	int			n_num_rngs;
211 	int			n_num_rngs_online;
212 	rng_entry_t		*n_rngs;
213 	clock_t			n_hc_secs;
214 	uint64_t		n_watchdog_cycles;
215 	uint64_t		n_accumulate_cycles;
216 } rng_ctl_data_t;
217 
218 typedef struct n2rng {
219 	kmutex_t		n_lock;
220 	dev_info_t		*n_dip;
221 	unsigned		n_flags;	/* dev state flags */
222 	uint_t			n_hvapi_major_version;
223 	uint_t			n_hvapi_minor_version;
224 	n2rng_binding_t		n_binding;
225 	char			*n_binding_name;
226 	rng_ctl_data_t		*n_ctl_data;	/* Only valid in ctl domain */
227 	kstat_t			*n_ksp;
228 	uint64_t		n_stats[DS_MAX];
229 	crypto_kcf_provider_handle_t	n_prov;
230 	fips_ensemble_t		n_frs;
231 	timeout_id_t		n_timeout_id;
232 	md_t			*n_mdp;
233 	uint64_t		n_sticks_per_usec;
234 	ddi_taskq_t		*n_taskq;
235 } n2rng_t;
236 
237 typedef kstat_named_t n2rng_kstat_bias_t[N2RNG_MAX_RNGS][N2RNG_NOSC];
238 
239 typedef struct n2rng_stat n2rng_stat_t;
240 struct n2rng_stat {
241 	kstat_named_t		ns_status;
242 	kstat_named_t		ns_algs[DS_MAX];
243 	kstat_named_t		ns_rngstate[N2RNG_MAX_RNGS];
244 	n2rng_kstat_bias_t	ns_rngbias;
245 	n2rng_kstat_bias_t	ns_rngentropy;
246 };
247 
248 #define	RNG_MODE_NORMAL			1
249 #define	RNG_MODE_DIAGNOSTIC		0
250 
251 #define	RNG_DIAG_CHUNK_SIZE		(N2RNG_MAX_READ / 8) /* as words */
252 #define	RNG_MAX_DATA_READ_ATTEMPTS	100
253 #define	RNG_RETRY_HLCHK_USECS		100000	/* retry every .1 seconds */
254 
255 #define	RNG_MAX_LOGIC_TEST_ATTEMPTS	3
256 #define	RNG_MAX_BUSY_ATTEMPTS		100
257 #define	RNG_MAX_BLOCK_ATTEMPTS		50000
258 #define	RNG_RETRY_BUSY_DELAY		1
259 
260 #define	RNG_DEFAULT_ACCUMULATE_CYCLES	2048
261 #define	RNG_CFG_RETRY_SECS		60 /* seconds between cfg retries */
262 
263 #define	RNG_DEFAULT_HC_SECS		0  /* seconds between health checks */
264 #define	RNG_EXTRA_WATCHDOG_SECS		60 /* added to hc time for watchdog */
265 
266 #define	LOG_ARG_SCALE			49
267 #define	LOG_VAL_SCALE			32
268 
269 void n2rng_sort(uint64_t *data, int log2_size);
270 int n2rng_noise_gen_preferred(n2rng_t *n2rng, int rngid);
271 int n2rng_config_test(n2rng_t *n2rng);
272 int n2rng_collect_diag_bits(n2rng_t *n2rng, int rngid,
273     n2rng_setup_t *collect_setupp, void *buffer, int numbytes,
274     n2rng_setup_t *exit_setupp, uint64_t exitstate);
275 int n2rng_getentropy(n2rng_t *n2rng, void *buffer, size_t size);
276 int n2rng_fips_random_init(n2rng_t *n2rng, fipsrandomstruct_t *frsp);
277 void n2rng_fips_random_fini(fipsrandomstruct_t *frsp);
278 int n2rng_do_health_check(n2rng_t *n2rng, int rngid);
279 void n2rng_renyi_entropy(uint64_t *buffer, int log2samples,
280     n2rng_osc_perf_t *metricp);
281 uint64_t n2rng_read_ctl(n2rng_t *n2rng, int rngid, uint64_t ctlregs_pa,
282     uint64_t *state, uint64_t *tdelta, uint64_t *wdelta);
283 uint64_t n2rng_ctl_wait(n2rng_t *n2rng, int rngid);
284 uint64_t n2rng_ctl_write(n2rng_t *n2rng, int rngid, uint64_t ctlregs_pa,
285     uint64_t newstate, uint64_t wtimeout, uint64_t *tdelta);
286 uint64_t n2rng_data_read_diag(n2rng_t *n2rng, int rngid, uint64_t data_pa,
287     size_t  datalen, uint64_t *tdelta);
288 uint64_t n2rng_check_ctl_access(n2rng_t *n2rng);
289 void n2rng_config_retry(n2rng_t *n2rng, clock_t seconds);
290 
291 #if defined(DEBUG)
292 
293 #define	DWARN		0x00000001
294 #define	DMA_ARGS	0x00000002
295 #define	DMA_LDST	0x00000004
296 #define	DNCS_QTAIL	0x00000008
297 #define	DATTACH		0x00000010
298 #define	DCFG		0x00000020
299 #define	DMOD		0x00000040  /* _init/_fini/_info/attach/detach */
300 #define	DENTRY		0x00000080  /* crypto routine entry/exit points */
301 #define	DHEALTH		0x00000100
302 #define	DCHATTY		0x00000200
303 #define	DKCF		0x00000400
304 #define	DALL		0xFFFFFFFF
305 
306 #define	DBG0	n2rng_dprintf
307 #define	DBG1	n2rng_dprintf
308 #define	DBG2	n2rng_dprintf
309 #define	DBG3	n2rng_dprintf
310 #define	DBG4	n2rng_dprintf
311 #define	DBG5	n2rng_dprintf
312 #define	DBG6	n2rng_dprintf
313 #define	DBGCALL(flag, func)	{ if (n2rng_dflagset(flag)) (void) func; }
314 
315 void	n2rng_dprintf(n2rng_t *, int, const char *, ...);
316 void	n2rng_dumphex(void *, int);
317 int	n2rng_dflagset(int);
318 
319 #else	/* !defined(DEBUG) */
320 
321 #define	DBG0(vca, lvl, fmt)
322 #define	DBG1(vca, lvl, fmt, arg1)
323 #define	DBG2(vca, lvl, fmt, arg1, arg2)
324 #define	DBG3(vca, lvl, fmt, arg1, arg2, arg3)
325 #define	DBG4(vca, lvl, fmt, arg1, arg2, arg3, arg4)
326 #define	DBG5(vca, lvl, fmt, arg1, arg2, arg3, arg4, arg5)
327 #define	DBG6(vca, lvl, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
328 #define	DBGCALL(flag, func)
329 
330 #endif	/* !defined(DEBUG) */
331 
332 /*
333  * n2rng_kcf.c
334  */
335 int n2rng_herr2kerr(uint64_t);
336 int n2rng_logic_test(n2rng_t *, int);
337 int n2rng_noise_gen_test_set(void);
338 int n2rng_init(n2rng_t *n2rng);
339 int n2rng_uninit(n2rng_t *n2rng);
340 int n2rng_register_provider(n2rng_t *n2rng);
341 int n2rng_unregister_provider(n2rng_t *n2rng);
342 void n2rng_failure(n2rng_t *n2rng);
343 void n2rng_unconfigured(n2rng_t *n2rng);
344 
345 /*
346  * n2rng_debug.c
347  */
348 void n2rng_error(n2rng_t *, const char *, ...);
349 void n2rng_diperror(dev_info_t *, const char *, ...);
350 void n2rng_dipverror(dev_info_t *, const char *, va_list);
351 
352 uint64_t hv_rng_get_diag_control(void);
353 uint64_t hv_rng_ctl_read(uint64_t ctlregs_pa, uint64_t *state,
354     uint64_t *tdelta);
355 uint64_t hv_rng_ctl_read_v2(uint64_t ctlregs_pa, uint64_t rngid,
356     uint64_t *state, uint64_t *tdelta, uint64_t *wdelta, uint64_t *wstate);
357 uint64_t hv_rng_ctl_write(uint64_t ctlregs_pa,
358     uint64_t newstate, uint64_t wtimeout, uint64_t *tdelta);
359 uint64_t hv_rng_ctl_write_v2(uint64_t ctlregs_pa,
360     uint64_t newstate, uint64_t wtimeout, uint64_t rngid);
361 uint64_t hv_rng_data_read_diag(uint64_t data_pa,
362     size_t  datalen, uint64_t *tdelta);
363 uint64_t hv_rng_data_read_diag_v2(uint64_t data_pa,
364     size_t  datalen, uint64_t rngid, uint64_t *tdelta);
365 uint64_t hv_rng_data_read(uint64_t data_pa, uint64_t *tdelta);
366 
367 #endif /* _KERNEL */
368 #endif /* !_ASM */
369 
370 #ifdef	__cplusplus
371 }
372 #endif
373 
374 #endif	/* _SYS_N2RNG_H */
375