xref: /titanic_50/usr/src/uts/common/sys/crypto/sched_impl.h (revision c77a61a72b5ecdc507d6cf104142edd371a16c84)
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_CRYPTO_SCHED_IMPL_H
27 #define	_SYS_CRYPTO_SCHED_IMPL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 /*
32  * Scheduler internal structures.
33  */
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 #include <sys/types.h>
40 #include <sys/mutex.h>
41 #include <sys/condvar.h>
42 #include <sys/door.h>
43 #include <sys/crypto/api.h>
44 #include <sys/crypto/spi.h>
45 #include <sys/crypto/impl.h>
46 #include <sys/crypto/common.h>
47 #include <sys/crypto/ops_impl.h>
48 
49 typedef void (kcf_func_t)(void *, int);
50 
51 typedef enum kcf_req_status {
52 	REQ_ALLOCATED = 1,
53 	REQ_WAITING,		/* At the framework level */
54 	REQ_INPROGRESS,		/* At the provider level */
55 	REQ_DONE,
56 	REQ_CANCELED
57 } kcf_req_status_t;
58 
59 typedef enum kcf_call_type {
60 	CRYPTO_SYNCH = 1,
61 	CRYPTO_ASYNCH
62 } kcf_call_type_t;
63 
64 #define	CHECK_RESTRICT(crq) (crq != NULL &&	\
65 	((crq)->cr_flag & CRYPTO_RESTRICTED))
66 
67 #define	CHECK_RESTRICT_FALSE	B_FALSE
68 
69 #define	CHECK_FASTPATH(crq, pd) ((crq) == NULL ||	\
70 	!((crq)->cr_flag & CRYPTO_ALWAYS_QUEUE)) &&	\
71 	(pd)->pd_prov_type == CRYPTO_SW_PROVIDER
72 
73 #define	KCF_KMFLAG(crq)	(((crq) == NULL) ? KM_SLEEP : KM_NOSLEEP)
74 
75 /*
76  * The framework keeps an internal handle to use in the adaptive
77  * asynchronous case. This is the case when a client has the
78  * CRYPTO_ALWAYS_QUEUE bit clear and a software provider is used for
79  * the request. The request is completed in the context of the calling
80  * thread and kernel memory must be allocated with KM_NOSLEEP.
81  *
82  * The framework passes a pointer to the handle in crypto_req_handle_t
83  * argument when it calls the SPI of the software provider. The macros
84  * KCF_RHNDL() and KCF_SWFP_RHNDL() are used to do this.
85  *
86  * When a provider asks the framework for kmflag value via
87  * crypto_kmflag(9S) we use REQHNDL2_KMFLAG() macro.
88  */
89 extern ulong_t kcf_swprov_hndl;
90 #define	KCF_RHNDL(kmflag) (((kmflag) == KM_SLEEP) ? NULL : &kcf_swprov_hndl)
91 #define	KCF_SWFP_RHNDL(crq) (((crq) == NULL) ? NULL : &kcf_swprov_hndl)
92 #define	REQHNDL2_KMFLAG(rhndl) \
93 	((rhndl == &kcf_swprov_hndl) ? KM_NOSLEEP : KM_SLEEP)
94 
95 /* Internal call_req flags. They start after the public ones in api.h */
96 
97 #define	CRYPTO_SETDUAL	0x00001000	/* Set the 'cont' boolean before */
98 					/* submitting the request */
99 #define	KCF_ISDUALREQ(crq)	\
100 	(((crq) == NULL) ? B_FALSE : (crq->cr_flag & CRYPTO_SETDUAL))
101 
102 typedef struct kcf_prov_tried {
103 	kcf_provider_desc_t	*pt_pd;
104 	struct kcf_prov_tried	*pt_next;
105 } kcf_prov_tried_t;
106 
107 #define	IS_FG_SUPPORTED(mdesc, fg)		\
108 	(((mdesc)->pm_mech_info.cm_func_group_mask & (fg)) != 0)
109 
110 #define	IS_PROVIDER_TRIED(pd, tlist)		\
111 	(tlist != NULL && is_in_triedlist(pd, tlist))
112 
113 #define	IS_RECOVERABLE(error)			\
114 	(error == CRYPTO_BUFFER_TOO_BIG ||	\
115 	error == CRYPTO_BUSY ||			\
116 	error == CRYPTO_DEVICE_ERROR ||		\
117 	error == CRYPTO_DEVICE_MEMORY ||	\
118 	error == CRYPTO_KEY_SIZE_RANGE ||	\
119 	error == CRYPTO_NO_PERMISSION)
120 
121 #define	KCF_ATOMIC_INCR(x)	atomic_add_32(&(x), 1)
122 #define	KCF_ATOMIC_DECR(x)	atomic_add_32(&(x), -1)
123 
124 /*
125  * Node structure for synchronous requests.
126  */
127 typedef struct kcf_sreq_node {
128 	/* Should always be the first field in this structure */
129 	kcf_call_type_t		sn_type;
130 	/*
131 	 * sn_cv and sr_lock are used to wait for the
132 	 * operation to complete. sn_lock also protects
133 	 * the sn_state field.
134 	 */
135 	kcondvar_t		sn_cv;
136 	kmutex_t		sn_lock;
137 	kcf_req_status_t	sn_state;
138 
139 	/*
140 	 * Return value from the operation. This will be
141 	 * one of the CRYPTO_* errors defined in common.h.
142 	 */
143 	int			sn_rv;
144 
145 	/*
146 	 * parameters to call the SPI with. This can be
147 	 * a pointer as we know the caller context/stack stays.
148 	 */
149 	struct kcf_req_params	*sn_params;
150 
151 	/* Internal context for this request */
152 	struct kcf_context	*sn_context;
153 
154 	/* Provider handling this request */
155 	kcf_provider_desc_t	*sn_provider;
156 } kcf_sreq_node_t;
157 
158 /*
159  * Node structure for asynchronous requests. A node can be on
160  * on a chain of requests hanging of the internal context
161  * structure and can be in the global software provider queue.
162  */
163 typedef struct kcf_areq_node {
164 	/* Should always be the first field in this structure */
165 	kcf_call_type_t		an_type;
166 
167 	/* an_lock protects the field an_state  */
168 	kmutex_t		an_lock;
169 	kcf_req_status_t	an_state;
170 	crypto_call_req_t	an_reqarg;
171 
172 	/*
173 	 * parameters to call the SPI with. We need to
174 	 * save the params since the caller stack can go away.
175 	 */
176 	struct kcf_req_params	an_params;
177 
178 	/*
179 	 * The next two fields should be NULL for operations that
180 	 * don't need a context.
181 	 */
182 	/* Internal context for this request */
183 	struct kcf_context	*an_context;
184 
185 	/* next in chain of requests for context */
186 	struct kcf_areq_node	*an_ctxchain_next;
187 
188 	boolean_t		an_is_my_turn;
189 	boolean_t		an_isdual;	/* for internal reuse */
190 
191 	/*
192 	 * Next and previous nodes in the global software
193 	 * queue. These fields are NULL for a hardware
194 	 * provider since we use a taskq there.
195 	 */
196 	struct kcf_areq_node	*an_next;
197 	struct kcf_areq_node	*an_prev;
198 
199 	/* Provider handling this request */
200 	kcf_provider_desc_t	*an_provider;
201 	kcf_prov_tried_t	*an_tried_plist;
202 
203 	struct kcf_areq_node	*an_idnext;	/* Next in ID hash */
204 	struct kcf_areq_node	*an_idprev;	/* Prev in ID hash */
205 	kcondvar_t		an_done;	/* Signal request completion */
206 	uint_t			an_refcnt;
207 } kcf_areq_node_t;
208 
209 #define	KCF_AREQ_REFHOLD(areq) {		\
210 	atomic_add_32(&(areq)->an_refcnt, 1);	\
211 	ASSERT((areq)->an_refcnt != 0);		\
212 }
213 
214 #define	KCF_AREQ_REFRELE(areq) {				\
215 	ASSERT((areq)->an_refcnt != 0);				\
216 	membar_exit();						\
217 	if (atomic_add_32_nv(&(areq)->an_refcnt, -1) == 0)	\
218 		kcf_free_req(areq);				\
219 }
220 
221 #define	GET_REQ_TYPE(arg) *((kcf_call_type_t *)(arg))
222 
223 #define	NOTIFY_CLIENT(areq, err) (*(areq)->an_reqarg.cr_callback_func)(\
224 	(areq)->an_reqarg.cr_callback_arg, err);
225 
226 /* For internally generated call requests for dual operations */
227 typedef	struct kcf_call_req {
228 	crypto_call_req_t	kr_callreq;	/* external client call req */
229 	kcf_req_params_t	kr_params;	/* Params saved for next call */
230 	kcf_areq_node_t		*kr_areq;	/* Use this areq */
231 	off_t			kr_saveoffset;
232 	size_t			kr_savelen;
233 } kcf_dual_req_t;
234 
235 /*
236  * The following are some what similar to macros in callo.h, which implement
237  * callout tables.
238  *
239  * The lower four bits of the ID are used to encode the table ID to
240  * index in to. The REQID_COUNTER_HIGH bit is used to avoid any check for
241  * wrap around when generating ID. We assume that there won't be a request
242  * which takes more time than 2^^(sizeof (long) - 5) other requests submitted
243  * after it. This ensures there won't be any ID collision.
244  */
245 #define	REQID_COUNTER_HIGH	(1UL << (8 * sizeof (long) - 1))
246 #define	REQID_COUNTER_SHIFT	4
247 #define	REQID_COUNTER_LOW	(1 << REQID_COUNTER_SHIFT)
248 #define	REQID_TABLES		16
249 #define	REQID_TABLE_MASK	(REQID_TABLES - 1)
250 
251 #define	REQID_BUCKETS		512
252 #define	REQID_BUCKET_MASK	(REQID_BUCKETS - 1)
253 #define	REQID_HASH(id)	(((id) >> REQID_COUNTER_SHIFT) & REQID_BUCKET_MASK)
254 
255 #define	GET_REQID(areq) (areq)->an_reqarg.cr_reqid
256 #define	SET_REQID(areq, val)	GET_REQID(areq) = val
257 
258 /*
259  * Hash table for async requests.
260  */
261 typedef struct kcf_reqid_table {
262 	kmutex_t		rt_lock;
263 	crypto_req_id_t		rt_curid;
264 	kcf_areq_node_t		*rt_idhash[REQID_BUCKETS];
265 } kcf_reqid_table_t;
266 
267 /*
268  * Global software provider queue structure. Requests to be
269  * handled by a SW provider and have the ALWAYS_QUEUE flag set
270  * get queued here.
271  */
272 typedef struct kcf_global_swq {
273 	/*
274 	 * gs_cv and gs_lock are used to wait for new requests.
275 	 * gs_lock protects the changes to the queue.
276 	 */
277 	kcondvar_t		gs_cv;
278 	kmutex_t		gs_lock;
279 	uint_t			gs_njobs;
280 	uint_t			gs_maxjobs;
281 	kcf_areq_node_t		*gs_first;
282 	kcf_areq_node_t		*gs_last;
283 } kcf_global_swq_t;
284 
285 
286 /*
287  * Internal representation of a canonical context. We contain crypto_ctx_t
288  * structure in order to have just one memory allocation. The SPI
289  * ((crypto_ctx_t *)ctx)->cc_framework_private maps to this structure.
290  */
291 typedef struct kcf_context {
292 	crypto_ctx_t		kc_glbl_ctx;
293 	uint_t			kc_refcnt;
294 	kcondvar_t		kc_in_use_cv;
295 	kmutex_t		kc_in_use_lock;
296 	/*
297 	 * kc_req_chain_first and kc_req_chain_last are used to chain
298 	 * multiple async requests using the same context. They should be
299 	 * NULL for sync requests.
300 	 */
301 	kcf_areq_node_t		*kc_req_chain_first;
302 	kcf_areq_node_t		*kc_req_chain_last;
303 	boolean_t		kc_need_signal;	/* Initialized to B_FALSE */
304 	kcf_provider_desc_t	*kc_prov_desc;	/* Prov. descriptor */
305 	struct kcf_context	*kc_secondctx;	/* for dual contexts */
306 } kcf_context_t;
307 
308 /*
309  * Bump up the reference count on the framework private context. A
310  * global context or a request that references this structure should
311  * do a hold.
312  */
313 #define	KCF_CONTEXT_REFHOLD(ictx) {		\
314 	atomic_add_32(&(ictx)->kc_refcnt, 1);	\
315 	ASSERT((ictx)->kc_refcnt != 0);		\
316 }
317 
318 /*
319  * Decrement the reference count on the framework private context.
320  * When the last reference is released, the framework private
321  * context structure is freed along with the global context.
322  */
323 #define	KCF_CONTEXT_REFRELE(ictx) {				\
324 	ASSERT((ictx)->kc_refcnt != 0);				\
325 	membar_exit();						\
326 	if (atomic_add_32_nv(&(ictx)->kc_refcnt, -1) == 0)	\
327 		kcf_free_context(ictx);				\
328 }
329 
330 /*
331  * Check if we can release the context now. In case of CRYPTO_QUEUED
332  * we do not release it as we can do it only after the provider notified
333  * us. In case of CRYPTO_BUSY, the client can retry the request using
334  * the context, so we do not release the context.
335  *
336  * This macro should be called only from the final routine in
337  * an init/update/final sequence. We do not release the context in case
338  * of update operations. We require the consumer to free it
339  * explicitly, in case it wants to abandon the operation. This is done
340  * as there may be mechanisms in ECB mode that can continue even if
341  * an operation on a block fails.
342  */
343 #define	KCF_CONTEXT_COND_RELEASE(rv, kcf_ctx) {			\
344 	if (KCF_CONTEXT_DONE(rv))				\
345 		KCF_CONTEXT_REFRELE(kcf_ctx);			\
346 }
347 
348 /*
349  * This macro determines whether we're done with a context.
350  */
351 #define	KCF_CONTEXT_DONE(rv)					\
352 	((rv) != CRYPTO_QUEUED && (rv) != CRYPTO_BUSY &&	\
353 	    (rv) != CRYPTO_BUFFER_TOO_SMALL)
354 
355 /*
356  * A crypto_ctx_template_t is internally a pointer to this struct
357  */
358 typedef	struct kcf_ctx_template {
359 	crypto_kcf_provider_handle_t	ct_prov_handle;	/* provider handle */
360 	uint_t				ct_generation;	/* generation # */
361 	size_t				ct_size;	/* for freeing */
362 	crypto_spi_ctx_template_t	ct_prov_tmpl;	/* context template */
363 							/* from the SW prov */
364 } kcf_ctx_template_t;
365 
366 /*
367  * Structure for pool of threads working on global software queue.
368  */
369 typedef struct kcf_pool {
370 	uint32_t	kp_threads;		/* Number of threads in pool */
371 	uint32_t	kp_idlethreads;		/* Idle threads in pool */
372 	uint32_t	kp_blockedthreads;	/* Blocked threads in pool */
373 
374 	/*
375 	 * cv & lock to monitor the condition when no threads
376 	 * are around. In this case the failover thread kicks in.
377 	 */
378 	kcondvar_t	kp_nothr_cv;
379 	kmutex_t	kp_thread_lock;
380 
381 	/* Userspace thread creator variables. */
382 	boolean_t	kp_signal_create_thread; /* Create requested flag  */
383 	int		kp_nthrs;		/* # of threads to create */
384 	boolean_t	kp_user_waiting;	/* Thread waiting for work */
385 
386 	/*
387 	 * cv & lock for the condition where more threads need to be
388 	 * created. kp_user_lock also protects the three fileds above.
389 	 */
390 	kcondvar_t	kp_user_cv;		/* Creator cond. variable */
391 	kmutex_t	kp_user_lock;		/* Creator lock */
392 } kcf_pool_t;
393 
394 
395 /*
396  * State of a crypto bufcall element.
397  */
398 typedef enum cbuf_state {
399 	CBUF_FREE = 1,
400 	CBUF_WAITING,
401 	CBUF_RUNNING
402 } cbuf_state_t;
403 
404 /*
405  * Structure of a crypto bufcall element.
406  */
407 typedef struct kcf_cbuf_elem {
408 	/*
409 	 * lock and cv to wait for CBUF_RUNNING to be done
410 	 * kc_lock also protects kc_state.
411 	 */
412 	kmutex_t		kc_lock;
413 	kcondvar_t		kc_cv;
414 	cbuf_state_t		kc_state;
415 
416 	struct kcf_cbuf_elem	*kc_next;
417 	struct kcf_cbuf_elem	*kc_prev;
418 
419 	void			(*kc_func)(void *arg);
420 	void			*kc_arg;
421 } kcf_cbuf_elem_t;
422 
423 /*
424  * State of a notify element.
425  */
426 typedef enum ntfy_elem_state {
427 	NTFY_WAITING = 1,
428 	NTFY_RUNNING
429 } ntfy_elem_state_t;
430 
431 /*
432  * Structure of a notify list element.
433  */
434 typedef struct kcf_ntfy_elem {
435 	/*
436 	 * lock and cv to wait for NTFY_RUNNING to be done.
437 	 * kn_lock also protects kn_state.
438 	 */
439 	kmutex_t			kn_lock;
440 	kcondvar_t			kn_cv;
441 	ntfy_elem_state_t		kn_state;
442 
443 	struct kcf_ntfy_elem		*kn_next;
444 	struct kcf_ntfy_elem		*kn_prev;
445 
446 	crypto_notify_callback_t	kn_func;
447 	uint32_t			kn_event_mask;
448 } kcf_ntfy_elem_t;
449 
450 
451 /*
452  * The following values are based on the assumption that it would
453  * take around eight cpus to load a hardware provider (This is true for
454  * at least one product) and a kernel client may come from different
455  * low-priority interrupt levels. We will have CYRPTO_TASKQ_MIN number
456  * of cached taskq entries. These are just reasonable estimates and
457  * might need to change in future.
458  */
459 #define	CYRPTO_TASKQ_MIN	64
460 #define	CRYPTO_TASKQ_MAX	1024
461 
462 extern int crypto_taskq_minalloc;
463 extern int crypto_taskq_maxalloc;
464 extern kcf_global_swq_t *gswq;
465 extern int kcf_maxthreads;
466 extern int kcf_minthreads;
467 
468 /* Door handle for talking to kcfd */
469 extern door_handle_t kcf_dh;
470 extern kmutex_t	 kcf_dh_lock;
471 
472 /*
473  * All pending crypto bufcalls are put on a list. cbuf_list_lock
474  * protects changes to this list.
475  */
476 extern kmutex_t cbuf_list_lock;
477 extern kcondvar_t cbuf_list_cv;
478 
479 /*
480  * All event subscribers are put on a list. kcf_notify_list_lock
481  * protects changes to this list.
482  */
483 extern kmutex_t ntfy_list_lock;
484 extern kcondvar_t ntfy_list_cv;
485 
486 boolean_t kcf_get_next_logical_provider_member(kcf_provider_desc_t *,
487     kcf_provider_desc_t *, kcf_provider_desc_t **);
488 extern int kcf_get_hardware_provider(crypto_mech_type_t, crypto_mech_type_t,
489     boolean_t, kcf_provider_desc_t *, kcf_provider_desc_t **,
490     crypto_func_group_t);
491 extern int kcf_get_hardware_provider_nomech(offset_t, offset_t,
492     boolean_t, kcf_provider_desc_t *, kcf_provider_desc_t **);
493 extern void kcf_free_triedlist(kcf_prov_tried_t *);
494 extern kcf_prov_tried_t *kcf_insert_triedlist(kcf_prov_tried_t **,
495     kcf_provider_desc_t *, int);
496 extern kcf_provider_desc_t *kcf_get_mech_provider(crypto_mech_type_t,
497     kcf_mech_entry_t **, int *, kcf_prov_tried_t *, crypto_func_group_t,
498     boolean_t, size_t);
499 extern kcf_provider_desc_t *kcf_get_dual_provider(crypto_mechanism_t *,
500     crypto_mechanism_t *, kcf_mech_entry_t **, crypto_mech_type_t *,
501     crypto_mech_type_t *, int *, kcf_prov_tried_t *,
502     crypto_func_group_t, crypto_func_group_t, boolean_t, size_t);
503 extern crypto_ctx_t *kcf_new_ctx(crypto_call_req_t  *, kcf_provider_desc_t *,
504     crypto_session_id_t);
505 extern int kcf_submit_request(kcf_provider_desc_t *, crypto_ctx_t *,
506     crypto_call_req_t *, kcf_req_params_t *, boolean_t);
507 extern void kcf_sched_init(void);
508 extern void kcf_sched_start(void);
509 extern void kcf_sop_done(kcf_sreq_node_t *, int);
510 extern void kcf_aop_done(kcf_areq_node_t *, int);
511 extern int common_submit_request(kcf_provider_desc_t *,
512     crypto_ctx_t *, kcf_req_params_t *, crypto_req_handle_t);
513 extern void kcf_free_context(kcf_context_t *);
514 
515 extern int kcf_svc_wait(int *);
516 extern int kcf_svc_do_run(void);
517 extern int kcf_verify_signature(kcf_provider_desc_t *);
518 extern struct modctl *kcf_get_modctl(crypto_provider_info_t *);
519 extern void verify_unverified_providers();
520 extern void kcf_free_req(kcf_areq_node_t *areq);
521 extern void crypto_bufcall_service(void);
522 
523 extern void kcf_walk_ntfylist(uint32_t, void *);
524 
525 extern kcf_dual_req_t *kcf_alloc_req(crypto_call_req_t *);
526 extern void kcf_next_req(void *, int);
527 extern void kcf_last_req(void *, int);
528 
529 #ifdef __cplusplus
530 }
531 #endif
532 
533 #endif /* _SYS_CRYPTO_SCHED_IMPL_H */
534