10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 54072Skrishna * Common Development and Distribution License (the "License"). 64072Skrishna * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*11030Sopensolaris@drydog.com * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _KERNELSESSION_H 270Sstevel@tonic-gate #define _KERNELSESSION_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #ifdef __cplusplus 300Sstevel@tonic-gate extern "C" { 310Sstevel@tonic-gate #endif 320Sstevel@tonic-gate 330Sstevel@tonic-gate #include <pthread.h> 340Sstevel@tonic-gate #include <sys/crypto/common.h> 350Sstevel@tonic-gate #include <security/pkcs11t.h> 360Sstevel@tonic-gate 370Sstevel@tonic-gate 380Sstevel@tonic-gate #define KERNELTOKEN_SESSION_MAGIC 0xECF00003 390Sstevel@tonic-gate 400Sstevel@tonic-gate typedef struct crypto_active_op { 410Sstevel@tonic-gate CK_MECHANISM mech; 420Sstevel@tonic-gate void *context; 430Sstevel@tonic-gate uint32_t flags; 440Sstevel@tonic-gate } crypto_active_op_t; 450Sstevel@tonic-gate 464072Skrishna #define EDIGEST_LENGTH 1024 474072Skrishna 484072Skrishna /* Used for emulating digest and HMAC mechs */ 494072Skrishna typedef struct digest_buf { 504072Skrishna uint8_t *buf; 514072Skrishna int buf_len; 524072Skrishna int indata_len; 534072Skrishna void *soft_sp; 544072Skrishna } digest_buf_t; 550Sstevel@tonic-gate 560Sstevel@tonic-gate /* 570Sstevel@tonic-gate * Definition for flags in crypto_active_op_t 584072Skrishna * 594072Skrishna * CRYPTO_EMULATE flag is set for a digest or sign/verify with a HMAC 604072Skrishna * mechanism, if the session slot has a CRYPTO_LIMITED_HASH_SUPPORT flag set. 614072Skrishna * CRYPTO_EMULATE_USING_SW flag is meaningful only when CRYPTO_EMULATE flag 624072Skrishna * is set. And CRYPTO_EMULATE_UPDATE_DONE flag is meaningful only when 634072Skrishna * CRYPTO_EMULATE_USING_SW flag is set. 640Sstevel@tonic-gate */ 654072Skrishna #define CRYPTO_OPERATION_ACTIVE 0x00000001 /* Cryptoki operation is active */ 664072Skrishna #define CRYPTO_OPERATION_UPDATE 0x00000002 /* Cryptoki multi-part op active */ 674072Skrishna #define CRYPTO_EMULATE 0x00000004 /* op needs emulation */ 684072Skrishna #define CRYPTO_EMULATE_USING_SW 0x00000008 /* ... use software */ 694072Skrishna #define CRYPTO_EMULATE_UPDATE_DONE 0x00000010 /* did at least one update */ 705616Skrishna #define CRYPTO_EMULATE_INIT_DONE 0x00000020 /* did init */ 71*11030Sopensolaris@drydog.com #define CRYPTO_OPERATION_INPLACE_OK 0x00000040 /* INPLACE_MECHANISM is true */ 720Sstevel@tonic-gate 730Sstevel@tonic-gate typedef struct session { 740Sstevel@tonic-gate CK_ULONG magic_marker; /* magic # be validated for integrity */ 750Sstevel@tonic-gate pthread_mutex_t session_mutex; /* session's mutex lock */ 760Sstevel@tonic-gate pthread_mutex_t ses_free_mutex; /* mutex used during closing session */ 770Sstevel@tonic-gate pthread_cond_t ses_free_cond; /* cond variable for signal and wait */ 780Sstevel@tonic-gate uint32_t ses_refcnt; /* session reference count */ 790Sstevel@tonic-gate uint32_t ses_close_sync; /* session closing flags */ 800Sstevel@tonic-gate crypto_session_id_t k_session; /* kernel session ID */ 810Sstevel@tonic-gate boolean_t ses_RO; /* RO or RW session flag */ 820Sstevel@tonic-gate CK_SLOT_ID ses_slotid; /* slotID saved from C_OpenSession() */ 830Sstevel@tonic-gate 840Sstevel@tonic-gate /* Place holder for parameters passed in the C_OpenSession */ 850Sstevel@tonic-gate CK_FLAGS flags; 860Sstevel@tonic-gate CK_NOTIFY Notify; 870Sstevel@tonic-gate CK_VOID_PTR pApplication; 880Sstevel@tonic-gate 890Sstevel@tonic-gate /* Pointers to form the global session list */ 900Sstevel@tonic-gate struct session *next; /* points to next session on the list */ 910Sstevel@tonic-gate struct session *prev; /* points to prev session on the list */ 920Sstevel@tonic-gate 930Sstevel@tonic-gate struct object *object_list; /* points to list of objects */ 940Sstevel@tonic-gate 950Sstevel@tonic-gate crypto_active_op_t digest; /* context of active digest operation */ 960Sstevel@tonic-gate crypto_active_op_t encrypt; /* context of active encrypt op */ 970Sstevel@tonic-gate crypto_active_op_t decrypt; /* context of active decrypt op */ 980Sstevel@tonic-gate crypto_active_op_t sign; /* context of active sign op */ 990Sstevel@tonic-gate crypto_active_op_t verify; /* context of active verify op */ 1000Sstevel@tonic-gate crypto_active_op_t find_objects; 1010Sstevel@tonic-gate } kernel_session_t; 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate /* 104214Smcpowers * The following structure is used to link the to-be-freed sessions 105214Smcpowers * into a linked list. The sessions on this linked list have 106214Smcpowers * not yet been freed via free() after C_CloseSession() call; instead 107214Smcpowers * they are added to this list. The actual free will take place when 108214Smcpowers * the number of sessions queued reaches MAX_SES_TO_BE_FREED, at which 109214Smcpowers * time the first session in the list will be freed. 110214Smcpowers */ 111214Smcpowers #define MAX_SES_TO_BE_FREED 300 112214Smcpowers 113214Smcpowers typedef struct ses_to_be_freed_list { 114214Smcpowers kernel_session_t *first; /* points to the first session in the list */ 115214Smcpowers kernel_session_t *last; /* points to the last session in the list */ 116214Smcpowers uint32_t count; /* current total sessions in the list */ 117214Smcpowers pthread_mutex_t ses_to_be_free_mutex; 118214Smcpowers } ses_to_be_freed_list_t; 119214Smcpowers 120214Smcpowers extern ses_to_be_freed_list_t ses_delay_freed; 121214Smcpowers 122214Smcpowers /* 1230Sstevel@tonic-gate * Flag definitions for ses_close_sync 1240Sstevel@tonic-gate */ 1250Sstevel@tonic-gate #define SESSION_IS_CLOSING 1 /* Session is in a closing state */ 1260Sstevel@tonic-gate #define SESSION_REFCNT_WAITING 2 /* Waiting for session reference */ 1270Sstevel@tonic-gate /* count to become zero */ 1280Sstevel@tonic-gate /* 1290Sstevel@tonic-gate * This macro is used to decrement the session reference count by one. 1300Sstevel@tonic-gate * 1310Sstevel@tonic-gate * The caller of this macro uses the argument lock_held to indicate that 1320Sstevel@tonic-gate * whether the caller holds the lock on the session or not. 1330Sstevel@tonic-gate * 1340Sstevel@tonic-gate * REFRELE macro does the following: 1350Sstevel@tonic-gate * 1) Get the session lock if the caller does not hold it. 1360Sstevel@tonic-gate * 2) Decrement the session reference count by one. 1370Sstevel@tonic-gate * 3) If the session reference count becomes zero after being decremented, 1380Sstevel@tonic-gate * and there is a closing session thread in the wait state, then 1390Sstevel@tonic-gate * call pthread_cond_signal() to wake up that thread who is blocked 1400Sstevel@tonic-gate * in the session deletion routine due to non-zero reference ount. 1410Sstevel@tonic-gate * 4) Always release the session lock. 1420Sstevel@tonic-gate */ 1430Sstevel@tonic-gate #define REFRELE(s, ses_lock_held) { \ 1440Sstevel@tonic-gate if (!ses_lock_held) \ 1450Sstevel@tonic-gate (void) pthread_mutex_lock(&s->session_mutex); \ 1460Sstevel@tonic-gate if ((--((s)->ses_refcnt) == 0) && \ 1470Sstevel@tonic-gate (s->ses_close_sync & SESSION_REFCNT_WAITING)) { \ 1480Sstevel@tonic-gate (void) pthread_mutex_unlock(&s->session_mutex); \ 1490Sstevel@tonic-gate (void) pthread_cond_signal(&s->ses_free_cond); \ 1500Sstevel@tonic-gate } else { \ 1510Sstevel@tonic-gate (void) pthread_mutex_unlock(&s->session_mutex); \ 1520Sstevel@tonic-gate } \ 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate /* 1570Sstevel@tonic-gate * Function Prototypes. 1580Sstevel@tonic-gate */ 1590Sstevel@tonic-gate CK_RV handle2session(CK_SESSION_HANDLE hSession, kernel_session_t **session_p); 1600Sstevel@tonic-gate 161214Smcpowers void kernel_delete_all_sessions(CK_SLOT_ID slotID, boolean_t wrapper_only); 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate void kernel_delete_all_objects_in_session(kernel_session_t *sp, 1640Sstevel@tonic-gate boolean_t wrapper_only); 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate CK_RV kernel_add_session(CK_SLOT_ID slotID, CK_FLAGS flags, 1670Sstevel@tonic-gate CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_ULONG *phSession); 1680Sstevel@tonic-gate 169214Smcpowers void kernel_delete_session(CK_SLOT_ID slotID, kernel_session_t *sp, 1700Sstevel@tonic-gate boolean_t lock_held, boolean_t wrapper_only); 1710Sstevel@tonic-gate 172214Smcpowers void kernel_session_delay_free(kernel_session_t *sp); 173214Smcpowers 1746824Srupertk void kernel_acquire_all_slots_mutexes(); 1756824Srupertk void kernel_release_all_slots_mutexes(); 1766824Srupertk 1770Sstevel@tonic-gate #ifdef __cplusplus 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate #endif 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate #endif /* _KERNELSESSION_H */ 182