impl.h revision 7623016fd42aadb1a19e2c2810fe6142c795c73b
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_CRYPTO_IMPL_H
#define _SYS_CRYPTO_IMPL_H
/*
* Kernel Cryptographic Framework private implementation definitions.
*/
#ifdef _KERNEL
#include <sys/tnf_probe.h>
#endif /* _KERNEL */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _KERNEL
/*
* Prefixes convention: structures internal to the kernel cryptographic
* framework start with 'kcf_'. Exposed structure start with 'crypto_'.
*/
/* Provider stats. Not protected. */
typedef struct kcf_prov_stats {
/* Various kcf stats. Not protected. */
typedef struct kcf_stats {
} kcf_stats_t;
typedef struct kcf_lock_withpad {
/*
* Per-CPU structure used by a provider to keep track of
* various counters.
*/
typedef struct kcf_prov_cpu {
int kp_holdcnt; /* can go negative! */
/*
* kcf_get_refcnt(pd) is the number of inflight requests to the
* provider. So, it is a good measure of the load on a provider when
* it is not in a busy state. Once a provider notifies it is busy, requests
* backup in the taskq. So, we use tq_nalloc in that case which gives
* the number of task entries in the task queue. Note that we do not
* acquire any locks here as it is not critical to get the exact number
* and the lock contention is too costly for this code path.
*/
/*
* The following two macros should be
* #define KCF_OPS_CLASSSIZE (KCF_LAST_OPSCLASS - KCF_FIRST_OPSCLASS + 2)
* #define KCF_MAXMECHTAB KCF_MAXCIPHER
*
* However, doing that would involve reorganizing the header file a bit.
* When impl.h is broken up (bug# 4703218), this will be done. For now,
* we hardcode these values.
*/
#define KCF_OPS_CLASSSIZE 8
#define KCF_MAXMECHTAB 32
/*
* Valid values for the state of a provider. The order of
* the elements is important.
*
* Routines which get a provider or the list of providers
* should pick only those that are either in KCF_PROV_READY state
* or in KCF_PROV_BUSY state.
*/
typedef enum {
KCF_PROV_ALLOCATED = 1,
/*
* state < KCF_PROV_READY means the provider can not
* be used at all.
*/
/*
* state > KCF_PROV_BUSY means the provider can not
* be used for new requests.
*/
/*
* Threads setting the following two states should do so only
* if the current state < KCF_PROV_DISABLED.
*/
/* Internal flags valid for pd_flags field */
#define KCF_PROV_RESTRICTED 0x40000000
/*
* A provider descriptor structure. There is one such structure per
* provider. It is allocated and initialized at registration time and
* freed when the provider unregisters.
*
* pd_prov_type: Provider type, hardware or software
* pd_sid: Session ID of the provider used by kernel clients.
* This is valid only for session-oriented providers.
* pd_taskq: taskq used to dispatch crypto requests
* pd_nbins: number of bins in pd_percpu_bins
* pd_percpu_bins: Pointer to an array of per-CPU structures
* containing a lock, a cv and various counters.
* pd_lock: lock protects pd_state and pd_provider_list
* pd_state: State value of the provider
* pd_provider_list: Used to cross-reference logical providers and their
* members. Not used for software providers.
* pd_resume_cv: cv to wait for state to change from KCF_PROV_BUSY
* pd_prov_handle: Provider handle specified by provider
* pd_ops_vector: The ops vector specified by Provider
* pd_mech_indx: Lookup table which maps a core framework mechanism
* number to an index in pd_mechanisms array
* pd_mechanisms: Array of mechanisms supported by the provider, specified
* by the provider during registration
* pd_mech_list_count: The number of entries in pi_mechanisms, specified
* by the provider during registration
* pd_name: Device name or module name
* pd_instance: Device instance
* pd_module_id: Module ID returned by modload
* pd_mctlp: Pointer to modctl structure for this provider
* pd_description: Provider description string
* pd_flags: bitwise OR of pi_flags from crypto_provider_info_t
* and other internal flags defined above.
* pd_hash_limit: Maximum data size that hash mechanisms of this provider
* can support.
* pd_kcf_prov_handle: KCF-private handle assigned by KCF
* pd_prov_id: Identification # assigned by KCF to provider
* pd_kstat: kstat associated with the provider
* pd_ks_data: kstat data
*/
typedef struct kcf_provider_desc {
struct kcf_provider_list *pd_provider_list;
char *pd_name;
int pd_module_id;
char *pd_description;
/* useful for making a list of providers */
typedef struct kcf_provider_list {
struct kcf_provider_list *pl_next;
struct kcf_provider_desc *pl_provider;
/*
* If a component has a reference to a kcf_provider_desc_t,
* it REFHOLD()s. A new provider descriptor which is referenced only
* by the providers table has a reference counter of one.
*/
#define KCF_PROV_REFHOLD(desc) { \
kcf_prov_cpu_t *mp; \
\
mp->kp_holdcnt++; \
}
#define KCF_PROV_REFRELE(desc) { \
kcf_prov_cpu_t *mp; \
\
mp->kp_holdcnt--; \
}
/*
* The JOB macros are used only for a hardware provider.
* Hardware providers can have holds that stay forever.
* So, the job counter is used to check if it is safe to
* unregister a provider.
*/
#define KCF_PROV_JOB_HOLD(mp) { \
}
#define KCF_PROV_JOB_RELE(mp) { \
}
if (doincr) \
KCF_PROV_JOB_RELE(mp); \
}
kcf_prov_cpu_t *mp; \
\
mp->kp_ndispatches++; \
if ((error) == CRYPTO_BUSY) \
mp->kp_nbusy_rval++; \
}
/* list of crypto_mech_info_t valid as the second mech in a dual operation */
typedef struct crypto_mech_info_list {
struct crypto_mech_info_list *ml_next;
/*
* An element in a mechanism provider descriptors chain.
* The kcf_prov_mech_desc_t is duplicated in every chain the provider belongs
* to. This is a small tradeoff memory vs mutex spinning time to access the
* common provider field.
*/
typedef struct kcf_prov_mech_desc {
/* and the notation shortcuts ... */
extern kcf_lock_withpad_t *me_mutexes;
sizeof (crypto_mech_type_t) - \
2 * sizeof (kcf_prov_mech_desc_t *) - \
/*
* A mechanism entry in an xxx_mech_tab[]. KCF_CPU_PAD needs
* to be adjusted if this structure is changed.
*/
typedef struct kcf_mech_entry {
/*
* Number of HW providers in the chain. There is only one
* SW provider. So, we need only a count of HW providers.
*/
int me_num_hwprov;
/*
* When a SW provider is present, this is the generation number that
* ensures no objects from old SW providers are used in the new one
*/
/*
* threshold for using hardware providers for this mech
*/
/*
* A policy descriptor structure. It is allocated and initialized
* when administrative ioctls load disabled mechanisms.
*
* pd_prov_type: Provider type, hardware or software
* pd_name: Device name or module name.
* pd_instance: Device instance.
* pd_refcnt: Reference counter for this policy descriptor
* pd_mutex: Protects array and count of disabled mechanisms.
* pd_disabled_count: Count of disabled mechanisms.
* pd_disabled_mechs: Array of disabled mechanisms.
*/
typedef struct kcf_policy_desc {
char *pd_name;
/*
* If a component has a reference to a kcf_policy_desc_t,
* it REFHOLD()s. A new policy descriptor which is referenced only
* by the policy table has a reference count of one.
*/
#define KCF_POLICY_REFHOLD(desc) { \
}
/*
* Releases a reference to a policy descriptor. When the last
* reference is released, the descriptor is freed.
*/
#define KCF_POLICY_REFRELE(desc) { \
membar_exit(); \
}
/*
* This entry stores the name of a software module and its
* mechanisms. The mechanisms are 'hints' that are used to
* trigger loading of the module.
*/
typedef struct kcf_soft_conf_entry {
struct kcf_soft_conf_entry *ce_next;
char *ce_name;
extern kmutex_t soft_config_mutex;
extern kcf_soft_conf_entry_t *soft_config_list;
/*
* Global tables. The sizes are from the predefined PKCS#11 v2.20 mechanisms,
* with a margin of few extra empty entry points
*/
KCF_MAXSIGN + KCF_MAXKEYOPS + \
extern kcf_mech_entry_t kcf_digest_mechs_tab[];
extern kcf_mech_entry_t kcf_cipher_mechs_tab[];
extern kcf_mech_entry_t kcf_mac_mechs_tab[];
extern kcf_mech_entry_t kcf_sign_mechs_tab[];
extern kcf_mech_entry_t kcf_keyops_mechs_tab[];
extern kcf_mech_entry_t kcf_misc_mechs_tab[];
extern kmutex_t kcf_mech_tabs_lock;
typedef enum {
KCF_DIGEST_CLASS = 1,
#define KCF_FIRST_OPSCLASS KCF_DIGEST_CLASS
#define KCF_LAST_OPSCLASS KCF_MISC_CLASS
/* The table of all the kcf_xxx_mech_tab[]s, indexed by kcf_ops_class */
typedef struct kcf_mech_entry_tab {
int met_size; /* Size of the met_tab[] */
extern kcf_mech_entry_tab_t kcf_mech_tabs_tab[];
/* ps_refcnt is protected by cm_lock in the crypto_minor structure */
typedef struct crypto_provider_session {
struct crypto_provider_session *ps_next;
typedef struct crypto_session_data {
void *sd_find_init_cookie;
#define CRYPTO_SESSION_IN_USE 0x00000001
#define CRYPTO_SESSION_IS_BUSY 0x00000002
#define CRYPTO_SESSION_IS_CLOSED 0x00000004
#define KCF_MAX_PIN_LEN 1024
/*
* Per-minor info.
*
* cm_lock protects everything in this structure except for cm_refcnt.
*/
typedef struct crypto_minor {
extern rctl_hndl_t rc_project_crypto_mem;
/*
* Return codes for internal functions
*/
/*
* kCF internal mechanism and function group for tracking RNG providers.
*/
#define SUN_RANDOM "random"
/*
* Wrappers for ops vectors. In the wrapper definitions below, the pd
* argument always corresponds to a pointer to a provider descriptor
* of type kcf_prov_desc_t.
*/
#define KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) \
#define KCF_PROV_NOSTORE_KEY_OPS(pd) \
/*
* Wrappers for crypto_control_ops(9S) entry points.
*/
(KCF_PROV_CONTROL_OPS(pd) && \
/*
* Wrappers for crypto_ctx_ops(9S) entry points.
*/
/*
* Wrappers for crypto_digest_ops(9S) entry points.
*/
/*
* The _ (underscore) in _digest is needed to avoid replacing the
* function digest().
*/
/*
* Wrappers for crypto_cipher_ops(9S) entry points.
*/
req) : \
ciphertext, req) : \
req) : \
/*
* Wrappers for crypto_mac_ops(9S) entry points.
*/
/*
* The _ (underscore) in _mac is needed to avoid replacing the
* function mac().
*/
req) ( \
req) : \
req) : \
/*
* Wrappers for crypto_sign_ops(9S) entry points.
*/
req) ( \
(KCF_PROV_SIGN_OPS(pd) && \
/*
* Wrappers for crypto_verify_ops(9S) entry points.
*/
req) ( \
req) ( \
(KCF_PROV_VERIFY_OPS(pd) && \
/* verify_recover() CSPI routine has different argument order than verify() */
/*
* verify_recover_atomic() CSPI routine has different argument order
* than verify_atomic().
*/
(KCF_PROV_VERIFY_OPS(pd) && \
/*
* Wrappers for crypto_dual_ops(9S) entry points.
*/
ciphertext, req) ( \
(KCF_PROV_DUAL_OPS(pd) && \
(KCF_PROV_DUAL_OPS(pd) && \
ciphertext, req) ( \
(KCF_PROV_DUAL_OPS(pd) && \
(KCF_PROV_DUAL_OPS(pd) && \
/*
* Wrappers for crypto_dual_cipher_mac_ops(9S) entry points.
*/
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
mac_ctx_template, req) : \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
decr_ctx_template, req) : \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
(KCF_PROV_DUAL_CIPHER_MAC_OPS(pd) && \
!= NULL) ? \
/*
* Wrappers for crypto_random_number_ops(9S) entry points.
*/
(KCF_PROV_RANDOM_OPS(pd) && \
/*
* Wrappers for crypto_session_ops(9S) entry points.
*
* ops_pd is the provider descriptor that supplies the ops_vector.
* pd is the descriptor that supplies the provider handle.
*/
(KCF_PROV_SESSION_OPS(ops_pd) && \
(KCF_PROV_SESSION_OPS(ops_pd) && \
(KCF_PROV_SESSION_OPS(pd) && \
(KCF_PROV_SESSION_OPS(pd) && \
/*
* Wrappers for crypto_object_ops(9S) entry points.
*/
new_object, req) ( \
(KCF_PROV_OBJECT_OPS(pd) && \
(KCF_PROV_OBJECT_OPS(pd) && \
(KCF_PROV_OBJECT_OPS(pd) && \
req) ( \
(KCF_PROV_OBJECT_OPS(pd) && \
req) ( \
(KCF_PROV_OBJECT_OPS(pd) && \
/*
* Wrappers for crypto_key_ops(9S) entry points.
*/
req) ( \
wrapped_key_len, req) ( \
req) : \
/*
* Wrappers for crypto_provider_management_ops(9S) entry points.
*
* ops_pd is the provider descriptor that supplies the ops_vector.
* pd is the descriptor that supplies the provider handle.
* Only ext_info needs two handles.
*/
(KCF_PROV_PROVIDER_OPS(ops_pd) && \
req) ( \
/*
* Wrappers for crypto_nostore_key_ops(9S) entry points.
*/
(KCF_PROV_NOSTORE_KEY_OPS(pd) && \
(KCF_PROV_NOSTORE_KEY_OPS(pd) && \
(KCF_PROV_NOSTORE_KEY_OPS(pd) && \
/*
* to the crypto and cryptoadmin modules.
*/
crypto_data_t *, crypto_call_req_t *);
crypto_data_t *, crypto_call_req_t *);
crypto_data_t *, crypto_call_req_t *);
crypto_data_t *, crypto_call_req_t *);
/* Private sign entry points exported by KCF */
crypto_data_t *, crypto_call_req_t *);
crypto_data_t *, crypto_call_req_t *);
/* Private verify entry points exported by KCF */
crypto_data_t *, crypto_call_req_t *);
crypto_data_t *, crypto_call_req_t *);
/* Private dual operations entry points exported by KCF */
/* Random Number Generation */
/* Provider Management */
/* Administrative */
/* Miscellaneous */
crypto_mech_name_t **, uint_t *, int);
extern void kcf_init_mech_tabs(void);
extern int kcf_add_mech_provider(short, kcf_provider_desc_t *,
kcf_prov_mech_desc_t **);
extern void kcf_remove_mech_provider(char *, kcf_provider_desc_t *);
extern void kcf_free_provider_desc(kcf_provider_desc_t *);
extern void kcf_soft_config_init(void);
extern int get_sw_provider_for_mech(crypto_mech_name_t, char **);
extern void redo_register_provider(kcf_provider_desc_t *);
extern void kcf_rnd_init();
extern boolean_t kcf_rngprov_check(void);
extern void kcf_rnd_chpoll(short, int, short *, struct pollhead **);
extern void kcf_rnd_schedule_timeout(boolean_t);
void *, void (*update)());
void *, void (*update)());
int kmflag);
ssize_t *);
/* Access to the provider's table */
extern void kcf_prov_tab_init(void);
extern int kcf_prov_tab_add_provider(kcf_provider_desc_t *);
extern int kcf_prov_tab_rem_provider(crypto_provider_id_t);
extern kcf_provider_desc_t *kcf_prov_tab_lookup_by_name(char *);
kcf_mech_entry_t **, boolean_t);
extern kmutex_t prov_tab_mutex;
extern boolean_t kcf_need_provtab_walk;
/* Access to the policy table */
extern void kcf_policy_tab_init(void);
extern void kcf_policy_free_desc(kcf_policy_desc_t *);
crypto_mech_name_t **);
extern kcf_policy_desc_t *kcf_policy_lookup_by_name(char *);
uint_t *, crypto_mech_name_t **);
extern boolean_t in_soft_config_list(char *);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_CRYPTO_IMPL_H */