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