kmsSession.h revision 12720:3db6e0082404
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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25#ifndef _KMSSESSION_H
26#define	_KMSSESSION_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include <stdio.h>
33#include <pthread.h>
34#include <sys/avl.h>
35#include <security/pkcs11t.h>
36
37#define	K_SOLARIS_PLATFORM
38#include "KMSAgent.h"
39
40#define	KMSTOKEN_SESSION_MAGIC	0xECF00004
41
42#define	CRYPTO_OPERATION_ACTIVE 0x01
43#define	CRYPTO_OPERATION_UPDATE 0x02
44
45typedef struct {
46	CK_MECHANISM	mech;
47	void		*context;
48	uint32_t	flags;
49} kms_active_op_t;
50
51typedef struct {
52	char *label;
53	avl_node_t nodep;
54} objlabel_t;
55
56#define	KMSOFFSETOF(s, m)	((size_t)(&(((s *)0)->m)))
57
58/*
59 * Data stored in the KMS profile config file.
60 */
61typedef struct {
62	char	name[BUFSIZ];
63	char	agentId[BUFSIZ];
64	char	agentAddr[BUFSIZ];
65	int	transTimeout;
66	int	failoverLimit;
67	int	discoveryFreq;
68	int	securityMode;
69} kms_cfg_info_t;
70
71typedef struct session {
72	CK_ULONG	magic_marker;	/* magic # be validated for integrity */
73	pthread_mutex_t	session_mutex;	/* session's mutex lock */
74	pthread_mutex_t ses_free_mutex;	/* mutex used during closing session */
75	pthread_cond_t	ses_free_cond;	/* cond variable for signal and wait */
76	uint32_t	ses_refcnt;	/* session reference count */
77	uint32_t	ses_close_sync;	/* session closing flags */
78	boolean_t	ses_RO;		/* RO or RW session flag */
79	CK_SLOT_ID	ses_slotid;	/* slotID saved from C_OpenSession() */
80
81	/* Place holder for parameters passed in the C_OpenSession */
82	CK_FLAGS	flags;
83	CK_NOTIFY	Notify;
84	CK_VOID_PTR	pApplication;
85
86	/* Pointers to form the global session list */
87	struct session	*next;		/* points to next session on the list */
88	struct session	*prev;		/* points to prev session on the list */
89
90	struct object	*object_list;	/* points to list of objects */
91
92	kms_active_op_t	find_objects;
93	kms_active_op_t	encrypt;
94	kms_active_op_t	decrypt;
95
96	kms_cfg_info_t	configInfo;
97
98	avl_tree_t	objlabel_tree;
99	KMSClientProfile kmsProfile;
100} kms_session_t;
101
102/*
103 * The following structure is used to link the to-be-freed sessions
104 * into a linked list. The sessions on this linked list have
105 * not yet been freed via free() after C_CloseSession() call; instead
106 * they are added to this list. The actual free will take place when
107 * the number of sessions queued reaches MAX_SES_TO_BE_FREED, at which
108 * time the first session in the list will be freed.
109 */
110#define	MAX_SES_TO_BE_FREED		300
111
112typedef struct ses_to_be_freed_list {
113	kms_session_t *first; /* points to the first session in the list */
114	kms_session_t *last;  /* points to the last session in the list */
115	uint32_t	count;   /* current total sessions in the list */
116	pthread_mutex_t ses_to_be_free_mutex;
117} ses_to_be_freed_list_t;
118
119extern ses_to_be_freed_list_t ses_delay_freed;
120extern CK_ULONG kms_session_cnt;
121extern CK_ULONG kms_session_rw_cnt;
122
123/*
124 * Flag definitions for ses_close_sync
125 */
126#define	SESSION_IS_CLOSING	1	/* Session is in a closing state */
127#define	SESSION_REFCNT_WAITING	2	/* Waiting for session reference */
128					/* count to become zero */
129/*
130 * This macro is used to decrement the session reference count by one.
131 *
132 * The caller of this macro uses the argument lock_held to indicate that
133 * whether the caller holds the lock on the session or not.
134 *
135 * REFRELE macro does the following:
136 * 1) Get the session lock if the caller does not hold it.
137 * 2) Decrement the session reference count by one.
138 * 3) If the session reference count becomes zero after being decremented,
139 *    and there is a closing session thread in the wait state, then
140 *    call pthread_cond_signal() to wake up that thread who is blocked
141 *    in the session deletion routine due to non-zero reference ount.
142 * 4) Always release the session lock.
143 */
144#define	REFRELE(s, ses_lock_held) { \
145	if (!ses_lock_held) \
146		(void) pthread_mutex_lock(&s->session_mutex);   \
147	if ((--((s)->ses_refcnt) == 0) &&    \
148	    (s->ses_close_sync & SESSION_REFCNT_WAITING)) {     \
149		(void) pthread_mutex_unlock(&s->session_mutex);   \
150		(void) pthread_cond_signal(&s->ses_free_cond); \
151	} else {        \
152		(void) pthread_mutex_unlock(&s->session_mutex);   \
153	}       \
154}
155
156
157/*
158 * Function Prototypes.
159 */
160CK_RV
161handle2session(CK_SESSION_HANDLE hSession, kms_session_t **session_p);
162
163void
164kms_delete_all_sessions(boolean_t wrapper_only);
165
166void
167kms_delete_all_objects_in_session(kms_session_t *sp,
168    boolean_t wrapper_only);
169
170CK_RV
171kms_add_session(CK_SLOT_ID slotID, CK_FLAGS flags,
172    CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_ULONG *phSession);
173
174void
175kms_delete_session(kms_session_t *sp,
176    boolean_t lock_held, boolean_t wrapper_only);
177
178void
179kms_session_delay_free(kms_session_t *sp);
180
181void kms_acquire_all_slots_mutexes();
182void kms_release_all_slots_mutexes();
183
184#ifdef	__cplusplus
185}
186#endif
187
188#endif /* _KMSSESSION_H */
189