mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Illumos Crypto Port module added to enable native encryption in zfs
A port of the Illumos Crypto Framework to a Linux kernel module (found in module/icp). This is needed to do the actual encryption work. We cannot use the Linux kernel's built in crypto api because it is only exported to GPL-licensed modules. Having the ICP also means the crypto code can run on any of the other kernels under OpenZFS. I ended up porting over most of the internals of the framework, which means that porting over other API calls (if we need them) should be fairly easy. Specifically, I have ported over the API functions related to encryption, digests, macs, and crypto templates. The ICP is able to use assembly-accelerated encryption on amd64 machines and AES-NI instructions on Intel chips that support it. There are place-holder directories for similar assembly optimizations for other architectures (although they have not been written). Signed-off-by: Tom Caputi <tcaputi@datto.com> Signed-off-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Issue #4329
This commit is contained in:
committed by
Brian Behlendorf
parent
be88e733a6
commit
0b04990a5d
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ASM_LINKAGE_H
|
||||
#define _SYS_ASM_LINKAGE_H
|
||||
|
||||
#if defined(__i386) || defined(__amd64)
|
||||
|
||||
#include <sys/ia32/asm_linkage.h> /* XX64 x86/sys/asm_linkage.h */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_ASM_LINKAGE_H */
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
|
||||
#ifndef _SYS_BITMAP_H
|
||||
#define _SYS_BITMAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(_ASM_INLINES) && \
|
||||
(defined(__i386) || defined(__amd64))
|
||||
#include <asm/bitmap.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Operations on bitmaps of arbitrary size
|
||||
* A bitmap is a vector of 1 or more ulong_t's.
|
||||
* The user of the package is responsible for range checks and keeping
|
||||
* track of sizes.
|
||||
*/
|
||||
|
||||
#ifdef _LP64
|
||||
#define BT_ULSHIFT 6 /* log base 2 of BT_NBIPUL, to extract word index */
|
||||
#define BT_ULSHIFT32 5 /* log base 2 of BT_NBIPUL, to extract word index */
|
||||
#else
|
||||
#define BT_ULSHIFT 5 /* log base 2 of BT_NBIPUL, to extract word index */
|
||||
#endif
|
||||
|
||||
#define BT_NBIPUL (1 << BT_ULSHIFT) /* n bits per ulong_t */
|
||||
#define BT_ULMASK (BT_NBIPUL - 1) /* to extract bit index */
|
||||
|
||||
#ifdef _LP64
|
||||
#define BT_NBIPUL32 (1 << BT_ULSHIFT32) /* n bits per ulong_t */
|
||||
#define BT_ULMASK32 (BT_NBIPUL32 - 1) /* to extract bit index */
|
||||
#define BT_ULMAXMASK 0xffffffffffffffff /* used by bt_getlowbit */
|
||||
#else
|
||||
#define BT_ULMAXMASK 0xffffffff
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bitmap is a ulong_t *, bitindex an index_t
|
||||
*
|
||||
* The macros BT_WIM and BT_BIW internal; there is no need
|
||||
* for users of this package to use them.
|
||||
*/
|
||||
|
||||
/*
|
||||
* word in map
|
||||
*/
|
||||
#define BT_WIM(bitmap, bitindex) \
|
||||
((bitmap)[(bitindex) >> BT_ULSHIFT])
|
||||
/*
|
||||
* bit in word
|
||||
*/
|
||||
#define BT_BIW(bitindex) \
|
||||
(1UL << ((bitindex) & BT_ULMASK))
|
||||
|
||||
#ifdef _LP64
|
||||
#define BT_WIM32(bitmap, bitindex) \
|
||||
((bitmap)[(bitindex) >> BT_ULSHIFT32])
|
||||
|
||||
#define BT_BIW32(bitindex) \
|
||||
(1UL << ((bitindex) & BT_ULMASK32))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These are public macros
|
||||
*
|
||||
* BT_BITOUL == n bits to n ulong_t's
|
||||
*/
|
||||
#define BT_BITOUL(nbits) \
|
||||
(((nbits) + BT_NBIPUL - 1l) / BT_NBIPUL)
|
||||
#define BT_SIZEOFMAP(nbits) \
|
||||
(BT_BITOUL(nbits) * sizeof (ulong_t))
|
||||
#define BT_TEST(bitmap, bitindex) \
|
||||
((BT_WIM((bitmap), (bitindex)) & BT_BIW(bitindex)) ? 1 : 0)
|
||||
#define BT_SET(bitmap, bitindex) \
|
||||
{ BT_WIM((bitmap), (bitindex)) |= BT_BIW(bitindex); }
|
||||
#define BT_CLEAR(bitmap, bitindex) \
|
||||
{ BT_WIM((bitmap), (bitindex)) &= ~BT_BIW(bitindex); }
|
||||
|
||||
#ifdef _LP64
|
||||
#define BT_BITOUL32(nbits) \
|
||||
(((nbits) + BT_NBIPUL32 - 1l) / BT_NBIPUL32)
|
||||
#define BT_SIZEOFMAP32(nbits) \
|
||||
(BT_BITOUL32(nbits) * sizeof (uint_t))
|
||||
#define BT_TEST32(bitmap, bitindex) \
|
||||
((BT_WIM32((bitmap), (bitindex)) & BT_BIW32(bitindex)) ? 1 : 0)
|
||||
#define BT_SET32(bitmap, bitindex) \
|
||||
{ BT_WIM32((bitmap), (bitindex)) |= BT_BIW32(bitindex); }
|
||||
#define BT_CLEAR32(bitmap, bitindex) \
|
||||
{ BT_WIM32((bitmap), (bitindex)) &= ~BT_BIW32(bitindex); }
|
||||
#endif /* _LP64 */
|
||||
|
||||
|
||||
/*
|
||||
* BIT_ONLYONESET is a private macro not designed for bitmaps of
|
||||
* arbitrary size. u must be an unsigned integer/long. It returns
|
||||
* true if one and only one bit is set in u.
|
||||
*/
|
||||
#define BIT_ONLYONESET(u) \
|
||||
((((u) == 0) ? 0 : ((u) & ((u) - 1)) == 0))
|
||||
|
||||
#ifndef _ASM
|
||||
|
||||
/*
|
||||
* return next available bit index from map with specified number of bits
|
||||
*/
|
||||
extern index_t bt_availbit(ulong_t *bitmap, size_t nbits);
|
||||
/*
|
||||
* find the highest order bit that is on, and is within or below
|
||||
* the word specified by wx
|
||||
*/
|
||||
extern int bt_gethighbit(ulong_t *mapp, int wx);
|
||||
extern int bt_range(ulong_t *bitmap, size_t *pos1, size_t *pos2,
|
||||
size_t end_pos);
|
||||
extern int bt_getlowbit(ulong_t *bitmap, size_t start, size_t stop);
|
||||
extern void bt_copy(ulong_t *, ulong_t *, ulong_t);
|
||||
|
||||
/*
|
||||
* find the parity
|
||||
*/
|
||||
extern int odd_parity(ulong_t);
|
||||
|
||||
/*
|
||||
* Atomically set/clear bits
|
||||
* Atomic exclusive operations will set "result" to "-1"
|
||||
* if the bit is already set/cleared. "result" will be set
|
||||
* to 0 otherwise.
|
||||
*/
|
||||
#define BT_ATOMIC_SET(bitmap, bitindex) \
|
||||
{ atomic_or_long(&(BT_WIM(bitmap, bitindex)), BT_BIW(bitindex)); }
|
||||
#define BT_ATOMIC_CLEAR(bitmap, bitindex) \
|
||||
{ atomic_and_long(&(BT_WIM(bitmap, bitindex)), ~BT_BIW(bitindex)); }
|
||||
|
||||
#define BT_ATOMIC_SET_EXCL(bitmap, bitindex, result) \
|
||||
{ result = atomic_set_long_excl(&(BT_WIM(bitmap, bitindex)), \
|
||||
(bitindex) % BT_NBIPUL); }
|
||||
#define BT_ATOMIC_CLEAR_EXCL(bitmap, bitindex, result) \
|
||||
{ result = atomic_clear_long_excl(&(BT_WIM(bitmap, bitindex)), \
|
||||
(bitindex) % BT_NBIPUL); }
|
||||
|
||||
/*
|
||||
* Extracts bits between index h (high, inclusive) and l (low, exclusive) from
|
||||
* u, which must be an unsigned integer.
|
||||
*/
|
||||
#define BITX(u, h, l) (((u) >> (l)) & ((1LU << ((h) - (l) + 1LU)) - 1LU))
|
||||
|
||||
#endif /* _ASM */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_BITMAP_H */
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_ELFSIGN_H
|
||||
#define _SYS_CRYPTO_ELFSIGN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Consolidation Private Interface for elfsign/libpkcs11/kcfd
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
/*
|
||||
* Project Private structures and types used for communication between kcfd
|
||||
* and KCF over the door.
|
||||
*/
|
||||
|
||||
typedef enum ELFsign_status_e {
|
||||
ELFSIGN_UNKNOWN,
|
||||
ELFSIGN_SUCCESS,
|
||||
ELFSIGN_FAILED,
|
||||
ELFSIGN_NOTSIGNED,
|
||||
ELFSIGN_INVALID_CERTPATH,
|
||||
ELFSIGN_INVALID_ELFOBJ,
|
||||
ELFSIGN_RESTRICTED
|
||||
} ELFsign_status_t;
|
||||
|
||||
#define KCF_KCFD_VERSION1 1
|
||||
#define SIG_MAX_LENGTH 1024
|
||||
|
||||
#define ELF_SIGNATURE_SECTION ".SUNW_signature"
|
||||
|
||||
typedef struct kcf_door_arg_s {
|
||||
short da_version;
|
||||
boolean_t da_iskernel;
|
||||
|
||||
union {
|
||||
char filename[MAXPATHLEN]; /* For request */
|
||||
|
||||
struct kcf_door_result_s { /* For response */
|
||||
ELFsign_status_t status;
|
||||
uint32_t siglen;
|
||||
uchar_t signature[1];
|
||||
} result;
|
||||
} da_u;
|
||||
} kcf_door_arg_t;
|
||||
|
||||
typedef uint32_t filesig_vers_t;
|
||||
|
||||
/*
|
||||
* File Signature Structure
|
||||
* Applicable to ELF and other file formats
|
||||
*/
|
||||
struct filesignatures {
|
||||
uint32_t filesig_cnt; /* count of signatures */
|
||||
uint32_t filesig_pad; /* unused */
|
||||
union {
|
||||
char filesig_data[1];
|
||||
struct filesig { /* one of these for each signature */
|
||||
uint32_t filesig_size;
|
||||
filesig_vers_t filesig_version;
|
||||
union {
|
||||
struct filesig_version1 {
|
||||
uint32_t filesig_v1_dnsize;
|
||||
uint32_t filesig_v1_sigsize;
|
||||
uint32_t filesig_v1_oidsize;
|
||||
char filesig_v1_data[1];
|
||||
} filesig_v1;
|
||||
struct filesig_version3 {
|
||||
uint64_t filesig_v3_time;
|
||||
uint32_t filesig_v3_dnsize;
|
||||
uint32_t filesig_v3_sigsize;
|
||||
uint32_t filesig_v3_oidsize;
|
||||
char filesig_v3_data[1];
|
||||
} filesig_v3;
|
||||
} _u2;
|
||||
} filesig_sig;
|
||||
uint64_t filesig_align;
|
||||
} _u1;
|
||||
};
|
||||
#define filesig_sig _u1.filesig_sig
|
||||
|
||||
#define filesig_v1_dnsize _u2.filesig_v1.filesig_v1_dnsize
|
||||
#define filesig_v1_sigsize _u2.filesig_v1.filesig_v1_sigsize
|
||||
#define filesig_v1_oidsize _u2.filesig_v1.filesig_v1_oidsize
|
||||
#define filesig_v1_data _u2.filesig_v1.filesig_v1_data
|
||||
|
||||
#define filesig_v3_time _u2.filesig_v3.filesig_v3_time
|
||||
#define filesig_v3_dnsize _u2.filesig_v3.filesig_v3_dnsize
|
||||
#define filesig_v3_sigsize _u2.filesig_v3.filesig_v3_sigsize
|
||||
#define filesig_v3_oidsize _u2.filesig_v3.filesig_v3_oidsize
|
||||
#define filesig_v3_data _u2.filesig_v3.filesig_v3_data
|
||||
|
||||
#define filesig_ALIGN(s) (((s) + sizeof (uint64_t) - 1) & \
|
||||
(-sizeof (uint64_t)))
|
||||
#define filesig_next(ptr) (struct filesig *)((void *)((char *)(ptr) + \
|
||||
filesig_ALIGN((ptr)->filesig_size)))
|
||||
|
||||
#define FILESIG_UNKNOWN 0 /* unrecognized version */
|
||||
#define FILESIG_VERSION1 1 /* version1, all but sig section */
|
||||
#define FILESIG_VERSION2 2 /* version1 format, SHF_ALLOC only */
|
||||
#define FILESIG_VERSION3 3 /* version3, all but sig section */
|
||||
#define FILESIG_VERSION4 4 /* version3 format, SHF_ALLOC only */
|
||||
|
||||
#define _PATH_KCFD_DOOR "/etc/svc/volatile/kcfd_door"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_ELFSIGN_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_IOCTLADMIN_H
|
||||
#define _SYS_CRYPTO_IOCTLADMIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/common.h>
|
||||
|
||||
#define ADMIN_IOCTL_DEVICE "/dev/cryptoadm"
|
||||
|
||||
#define CRYPTOADMIN(x) (('y' << 8) | (x))
|
||||
|
||||
/*
|
||||
* Administrative IOCTLs
|
||||
*/
|
||||
|
||||
typedef struct crypto_get_dev_list {
|
||||
uint_t dl_return_value;
|
||||
uint_t dl_dev_count;
|
||||
crypto_dev_list_entry_t dl_devs[1];
|
||||
} crypto_get_dev_list_t;
|
||||
|
||||
typedef struct crypto_get_soft_list {
|
||||
uint_t sl_return_value;
|
||||
uint_t sl_soft_count;
|
||||
size_t sl_soft_len;
|
||||
caddr_t sl_soft_names;
|
||||
} crypto_get_soft_list_t;
|
||||
|
||||
typedef struct crypto_get_dev_info {
|
||||
uint_t di_return_value;
|
||||
char di_dev_name[MAXNAMELEN];
|
||||
uint_t di_dev_instance;
|
||||
uint_t di_count;
|
||||
crypto_mech_name_t di_list[1];
|
||||
} crypto_get_dev_info_t;
|
||||
|
||||
typedef struct crypto_get_soft_info {
|
||||
uint_t si_return_value;
|
||||
char si_name[MAXNAMELEN];
|
||||
uint_t si_count;
|
||||
crypto_mech_name_t si_list[1];
|
||||
} crypto_get_soft_info_t;
|
||||
|
||||
typedef struct crypto_load_dev_disabled {
|
||||
uint_t dd_return_value;
|
||||
char dd_dev_name[MAXNAMELEN];
|
||||
uint_t dd_dev_instance;
|
||||
uint_t dd_count;
|
||||
crypto_mech_name_t dd_list[1];
|
||||
} crypto_load_dev_disabled_t;
|
||||
|
||||
typedef struct crypto_load_soft_disabled {
|
||||
uint_t sd_return_value;
|
||||
char sd_name[MAXNAMELEN];
|
||||
uint_t sd_count;
|
||||
crypto_mech_name_t sd_list[1];
|
||||
} crypto_load_soft_disabled_t;
|
||||
|
||||
typedef struct crypto_unload_soft_module {
|
||||
uint_t sm_return_value;
|
||||
char sm_name[MAXNAMELEN];
|
||||
} crypto_unload_soft_module_t;
|
||||
|
||||
typedef struct crypto_load_soft_config {
|
||||
uint_t sc_return_value;
|
||||
char sc_name[MAXNAMELEN];
|
||||
uint_t sc_count;
|
||||
crypto_mech_name_t sc_list[1];
|
||||
} crypto_load_soft_config_t;
|
||||
|
||||
typedef struct crypto_load_door {
|
||||
uint_t ld_return_value;
|
||||
uint_t ld_did;
|
||||
} crypto_load_door_t;
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef _SYSCALL32
|
||||
|
||||
typedef struct crypto_get_soft_list32 {
|
||||
uint32_t sl_return_value;
|
||||
uint32_t sl_soft_count;
|
||||
size32_t sl_soft_len;
|
||||
caddr32_t sl_soft_names;
|
||||
} crypto_get_soft_list32_t;
|
||||
|
||||
#endif /* _SYSCALL32 */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define CRYPTO_GET_VERSION CRYPTOADMIN(1)
|
||||
#define CRYPTO_GET_DEV_LIST CRYPTOADMIN(2)
|
||||
#define CRYPTO_GET_SOFT_LIST CRYPTOADMIN(3)
|
||||
#define CRYPTO_GET_DEV_INFO CRYPTOADMIN(4)
|
||||
#define CRYPTO_GET_SOFT_INFO CRYPTOADMIN(5)
|
||||
#define CRYPTO_LOAD_DEV_DISABLED CRYPTOADMIN(8)
|
||||
#define CRYPTO_LOAD_SOFT_DISABLED CRYPTOADMIN(9)
|
||||
#define CRYPTO_UNLOAD_SOFT_MODULE CRYPTOADMIN(10)
|
||||
#define CRYPTO_LOAD_SOFT_CONFIG CRYPTOADMIN(11)
|
||||
#define CRYPTO_POOL_CREATE CRYPTOADMIN(12)
|
||||
#define CRYPTO_POOL_WAIT CRYPTOADMIN(13)
|
||||
#define CRYPTO_POOL_RUN CRYPTOADMIN(14)
|
||||
#define CRYPTO_LOAD_DOOR CRYPTOADMIN(15)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_IOCTLADMIN_H */
|
||||
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_OPS_IMPL_H
|
||||
#define _SYS_CRYPTO_OPS_IMPL_H
|
||||
|
||||
/*
|
||||
* Scheduler internal structures.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/api.h>
|
||||
#include <sys/crypto/spi.h>
|
||||
#include <sys/crypto/impl.h>
|
||||
#include <sys/crypto/common.h>
|
||||
|
||||
/*
|
||||
* The parameters needed for each function group are batched
|
||||
* in one structure. This is much simpler than having a
|
||||
* separate structure for each function.
|
||||
*
|
||||
* In some cases, a field is generically named to keep the
|
||||
* structure small. The comments indicate these cases.
|
||||
*/
|
||||
typedef struct kcf_digest_ops_params {
|
||||
crypto_session_id_t do_sid;
|
||||
crypto_mech_type_t do_framework_mechtype;
|
||||
crypto_mechanism_t do_mech;
|
||||
crypto_data_t *do_data;
|
||||
crypto_data_t *do_digest;
|
||||
crypto_key_t *do_digest_key; /* Argument for digest_key() */
|
||||
} kcf_digest_ops_params_t;
|
||||
|
||||
typedef struct kcf_mac_ops_params {
|
||||
crypto_session_id_t mo_sid;
|
||||
crypto_mech_type_t mo_framework_mechtype;
|
||||
crypto_mechanism_t mo_mech;
|
||||
crypto_key_t *mo_key;
|
||||
crypto_data_t *mo_data;
|
||||
crypto_data_t *mo_mac;
|
||||
crypto_spi_ctx_template_t mo_templ;
|
||||
} kcf_mac_ops_params_t;
|
||||
|
||||
typedef struct kcf_encrypt_ops_params {
|
||||
crypto_session_id_t eo_sid;
|
||||
crypto_mech_type_t eo_framework_mechtype;
|
||||
crypto_mechanism_t eo_mech;
|
||||
crypto_key_t *eo_key;
|
||||
crypto_data_t *eo_plaintext;
|
||||
crypto_data_t *eo_ciphertext;
|
||||
crypto_spi_ctx_template_t eo_templ;
|
||||
} kcf_encrypt_ops_params_t;
|
||||
|
||||
typedef struct kcf_decrypt_ops_params {
|
||||
crypto_session_id_t dop_sid;
|
||||
crypto_mech_type_t dop_framework_mechtype;
|
||||
crypto_mechanism_t dop_mech;
|
||||
crypto_key_t *dop_key;
|
||||
crypto_data_t *dop_ciphertext;
|
||||
crypto_data_t *dop_plaintext;
|
||||
crypto_spi_ctx_template_t dop_templ;
|
||||
} kcf_decrypt_ops_params_t;
|
||||
|
||||
typedef struct kcf_sign_ops_params {
|
||||
crypto_session_id_t so_sid;
|
||||
crypto_mech_type_t so_framework_mechtype;
|
||||
crypto_mechanism_t so_mech;
|
||||
crypto_key_t *so_key;
|
||||
crypto_data_t *so_data;
|
||||
crypto_data_t *so_signature;
|
||||
crypto_spi_ctx_template_t so_templ;
|
||||
} kcf_sign_ops_params_t;
|
||||
|
||||
typedef struct kcf_verify_ops_params {
|
||||
crypto_session_id_t vo_sid;
|
||||
crypto_mech_type_t vo_framework_mechtype;
|
||||
crypto_mechanism_t vo_mech;
|
||||
crypto_key_t *vo_key;
|
||||
crypto_data_t *vo_data;
|
||||
crypto_data_t *vo_signature;
|
||||
crypto_spi_ctx_template_t vo_templ;
|
||||
} kcf_verify_ops_params_t;
|
||||
|
||||
typedef struct kcf_encrypt_mac_ops_params {
|
||||
crypto_session_id_t em_sid;
|
||||
crypto_mech_type_t em_framework_encr_mechtype;
|
||||
crypto_mechanism_t em_encr_mech;
|
||||
crypto_key_t *em_encr_key;
|
||||
crypto_mech_type_t em_framework_mac_mechtype;
|
||||
crypto_mechanism_t em_mac_mech;
|
||||
crypto_key_t *em_mac_key;
|
||||
crypto_data_t *em_plaintext;
|
||||
crypto_dual_data_t *em_ciphertext;
|
||||
crypto_data_t *em_mac;
|
||||
crypto_spi_ctx_template_t em_encr_templ;
|
||||
crypto_spi_ctx_template_t em_mac_templ;
|
||||
} kcf_encrypt_mac_ops_params_t;
|
||||
|
||||
typedef struct kcf_mac_decrypt_ops_params {
|
||||
crypto_session_id_t md_sid;
|
||||
crypto_mech_type_t md_framework_mac_mechtype;
|
||||
crypto_mechanism_t md_mac_mech;
|
||||
crypto_key_t *md_mac_key;
|
||||
crypto_mech_type_t md_framework_decr_mechtype;
|
||||
crypto_mechanism_t md_decr_mech;
|
||||
crypto_key_t *md_decr_key;
|
||||
crypto_dual_data_t *md_ciphertext;
|
||||
crypto_data_t *md_mac;
|
||||
crypto_data_t *md_plaintext;
|
||||
crypto_spi_ctx_template_t md_mac_templ;
|
||||
crypto_spi_ctx_template_t md_decr_templ;
|
||||
} kcf_mac_decrypt_ops_params_t;
|
||||
|
||||
typedef struct kcf_random_number_ops_params {
|
||||
crypto_session_id_t rn_sid;
|
||||
uchar_t *rn_buf;
|
||||
size_t rn_buflen;
|
||||
uint_t rn_entropy_est;
|
||||
uint32_t rn_flags;
|
||||
} kcf_random_number_ops_params_t;
|
||||
|
||||
/*
|
||||
* so_pd is useful when the provider descriptor (pd) supplying the
|
||||
* provider handle is different from the pd supplying the ops vector.
|
||||
* This is the case for session open/close where so_pd can be the pd
|
||||
* of a logical provider. The pd supplying the ops vector is passed
|
||||
* as an argument to kcf_submit_request().
|
||||
*/
|
||||
typedef struct kcf_session_ops_params {
|
||||
crypto_session_id_t *so_sid_ptr;
|
||||
crypto_session_id_t so_sid;
|
||||
crypto_user_type_t so_user_type;
|
||||
char *so_pin;
|
||||
size_t so_pin_len;
|
||||
kcf_provider_desc_t *so_pd;
|
||||
} kcf_session_ops_params_t;
|
||||
|
||||
typedef struct kcf_object_ops_params {
|
||||
crypto_session_id_t oo_sid;
|
||||
crypto_object_id_t oo_object_id;
|
||||
crypto_object_attribute_t *oo_template;
|
||||
uint_t oo_attribute_count;
|
||||
crypto_object_id_t *oo_object_id_ptr;
|
||||
size_t *oo_object_size;
|
||||
void **oo_find_init_pp_ptr;
|
||||
void *oo_find_pp;
|
||||
uint_t oo_max_object_count;
|
||||
uint_t *oo_object_count_ptr;
|
||||
} kcf_object_ops_params_t;
|
||||
|
||||
/*
|
||||
* ko_key is used to encode wrapping key in key_wrap() and
|
||||
* unwrapping key in key_unwrap(). ko_key_template and
|
||||
* ko_key_attribute_count are used to encode public template
|
||||
* and public template attr count in key_generate_pair().
|
||||
* kops->ko_key_object_id_ptr is used to encode public key
|
||||
* in key_generate_pair().
|
||||
*/
|
||||
typedef struct kcf_key_ops_params {
|
||||
crypto_session_id_t ko_sid;
|
||||
crypto_mech_type_t ko_framework_mechtype;
|
||||
crypto_mechanism_t ko_mech;
|
||||
crypto_object_attribute_t *ko_key_template;
|
||||
uint_t ko_key_attribute_count;
|
||||
crypto_object_id_t *ko_key_object_id_ptr;
|
||||
crypto_object_attribute_t *ko_private_key_template;
|
||||
uint_t ko_private_key_attribute_count;
|
||||
crypto_object_id_t *ko_private_key_object_id_ptr;
|
||||
crypto_key_t *ko_key;
|
||||
uchar_t *ko_wrapped_key;
|
||||
size_t *ko_wrapped_key_len_ptr;
|
||||
crypto_object_attribute_t *ko_out_template1;
|
||||
crypto_object_attribute_t *ko_out_template2;
|
||||
uint_t ko_out_attribute_count1;
|
||||
uint_t ko_out_attribute_count2;
|
||||
} kcf_key_ops_params_t;
|
||||
|
||||
/*
|
||||
* po_pin and po_pin_len are used to encode new_pin and new_pin_len
|
||||
* when wrapping set_pin() function parameters.
|
||||
*
|
||||
* po_pd is useful when the provider descriptor (pd) supplying the
|
||||
* provider handle is different from the pd supplying the ops vector.
|
||||
* This is true for the ext_info provider entry point where po_pd
|
||||
* can be the pd of a logical provider. The pd supplying the ops vector
|
||||
* is passed as an argument to kcf_submit_request().
|
||||
*/
|
||||
typedef struct kcf_provmgmt_ops_params {
|
||||
crypto_session_id_t po_sid;
|
||||
char *po_pin;
|
||||
size_t po_pin_len;
|
||||
char *po_old_pin;
|
||||
size_t po_old_pin_len;
|
||||
char *po_label;
|
||||
crypto_provider_ext_info_t *po_ext_info;
|
||||
kcf_provider_desc_t *po_pd;
|
||||
} kcf_provmgmt_ops_params_t;
|
||||
|
||||
/*
|
||||
* The operation type within a function group.
|
||||
*/
|
||||
typedef enum kcf_op_type {
|
||||
/* common ops for all mechanisms */
|
||||
KCF_OP_INIT = 1,
|
||||
KCF_OP_SINGLE, /* pkcs11 sense. So, INIT is already done */
|
||||
KCF_OP_UPDATE,
|
||||
KCF_OP_FINAL,
|
||||
KCF_OP_ATOMIC,
|
||||
|
||||
/* digest_key op */
|
||||
KCF_OP_DIGEST_KEY,
|
||||
|
||||
/* mac specific op */
|
||||
KCF_OP_MAC_VERIFY_ATOMIC,
|
||||
|
||||
/* mac/cipher specific op */
|
||||
KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC,
|
||||
|
||||
/* sign_recover ops */
|
||||
KCF_OP_SIGN_RECOVER_INIT,
|
||||
KCF_OP_SIGN_RECOVER,
|
||||
KCF_OP_SIGN_RECOVER_ATOMIC,
|
||||
|
||||
/* verify_recover ops */
|
||||
KCF_OP_VERIFY_RECOVER_INIT,
|
||||
KCF_OP_VERIFY_RECOVER,
|
||||
KCF_OP_VERIFY_RECOVER_ATOMIC,
|
||||
|
||||
/* random number ops */
|
||||
KCF_OP_RANDOM_SEED,
|
||||
KCF_OP_RANDOM_GENERATE,
|
||||
|
||||
/* session management ops */
|
||||
KCF_OP_SESSION_OPEN,
|
||||
KCF_OP_SESSION_CLOSE,
|
||||
KCF_OP_SESSION_LOGIN,
|
||||
KCF_OP_SESSION_LOGOUT,
|
||||
|
||||
/* object management ops */
|
||||
KCF_OP_OBJECT_CREATE,
|
||||
KCF_OP_OBJECT_COPY,
|
||||
KCF_OP_OBJECT_DESTROY,
|
||||
KCF_OP_OBJECT_GET_SIZE,
|
||||
KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE,
|
||||
KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE,
|
||||
KCF_OP_OBJECT_FIND_INIT,
|
||||
KCF_OP_OBJECT_FIND,
|
||||
KCF_OP_OBJECT_FIND_FINAL,
|
||||
|
||||
/* key management ops */
|
||||
KCF_OP_KEY_GENERATE,
|
||||
KCF_OP_KEY_GENERATE_PAIR,
|
||||
KCF_OP_KEY_WRAP,
|
||||
KCF_OP_KEY_UNWRAP,
|
||||
KCF_OP_KEY_DERIVE,
|
||||
KCF_OP_KEY_CHECK,
|
||||
|
||||
/* provider management ops */
|
||||
KCF_OP_MGMT_EXTINFO,
|
||||
KCF_OP_MGMT_INITTOKEN,
|
||||
KCF_OP_MGMT_INITPIN,
|
||||
KCF_OP_MGMT_SETPIN
|
||||
} kcf_op_type_t;
|
||||
|
||||
/*
|
||||
* The operation groups that need wrapping of parameters. This is somewhat
|
||||
* similar to the function group type in spi.h except that this also includes
|
||||
* all the functions that don't have a mechanism.
|
||||
*
|
||||
* The wrapper macros should never take these enum values as an argument.
|
||||
* Rather, they are assigned in the macro itself since they are known
|
||||
* from the macro name.
|
||||
*/
|
||||
typedef enum kcf_op_group {
|
||||
KCF_OG_DIGEST = 1,
|
||||
KCF_OG_MAC,
|
||||
KCF_OG_ENCRYPT,
|
||||
KCF_OG_DECRYPT,
|
||||
KCF_OG_SIGN,
|
||||
KCF_OG_VERIFY,
|
||||
KCF_OG_ENCRYPT_MAC,
|
||||
KCF_OG_MAC_DECRYPT,
|
||||
KCF_OG_RANDOM,
|
||||
KCF_OG_SESSION,
|
||||
KCF_OG_OBJECT,
|
||||
KCF_OG_KEY,
|
||||
KCF_OG_PROVMGMT,
|
||||
KCF_OG_NOSTORE_KEY
|
||||
} kcf_op_group_t;
|
||||
|
||||
/*
|
||||
* The kcf_op_type_t enum values used here should be only for those
|
||||
* operations for which there is a k-api routine in sys/crypto/api.h.
|
||||
*/
|
||||
#define IS_INIT_OP(ftype) ((ftype) == KCF_OP_INIT)
|
||||
#define IS_SINGLE_OP(ftype) ((ftype) == KCF_OP_SINGLE)
|
||||
#define IS_UPDATE_OP(ftype) ((ftype) == KCF_OP_UPDATE)
|
||||
#define IS_FINAL_OP(ftype) ((ftype) == KCF_OP_FINAL)
|
||||
#define IS_ATOMIC_OP(ftype) ( \
|
||||
(ftype) == KCF_OP_ATOMIC || (ftype) == KCF_OP_MAC_VERIFY_ATOMIC || \
|
||||
(ftype) == KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC || \
|
||||
(ftype) == KCF_OP_SIGN_RECOVER_ATOMIC || \
|
||||
(ftype) == KCF_OP_VERIFY_RECOVER_ATOMIC)
|
||||
|
||||
/*
|
||||
* Keep the parameters associated with a request around.
|
||||
* We need to pass them to the SPI.
|
||||
*/
|
||||
typedef struct kcf_req_params {
|
||||
kcf_op_group_t rp_opgrp;
|
||||
kcf_op_type_t rp_optype;
|
||||
|
||||
union {
|
||||
kcf_digest_ops_params_t digest_params;
|
||||
kcf_mac_ops_params_t mac_params;
|
||||
kcf_encrypt_ops_params_t encrypt_params;
|
||||
kcf_decrypt_ops_params_t decrypt_params;
|
||||
kcf_sign_ops_params_t sign_params;
|
||||
kcf_verify_ops_params_t verify_params;
|
||||
kcf_encrypt_mac_ops_params_t encrypt_mac_params;
|
||||
kcf_mac_decrypt_ops_params_t mac_decrypt_params;
|
||||
kcf_random_number_ops_params_t random_number_params;
|
||||
kcf_session_ops_params_t session_params;
|
||||
kcf_object_ops_params_t object_params;
|
||||
kcf_key_ops_params_t key_params;
|
||||
kcf_provmgmt_ops_params_t provmgmt_params;
|
||||
} rp_u;
|
||||
} kcf_req_params_t;
|
||||
|
||||
|
||||
/*
|
||||
* The ioctl/k-api code should bundle the parameters into a kcf_req_params_t
|
||||
* structure before calling a scheduler routine. The following macros are
|
||||
* available for that purpose.
|
||||
*
|
||||
* For the most part, the macro arguments closely correspond to the
|
||||
* function parameters. In some cases, we use generic names. The comments
|
||||
* for the structure should indicate these cases.
|
||||
*/
|
||||
#define KCF_WRAP_DIGEST_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _digest) { \
|
||||
kcf_digest_ops_params_t *dops = &(req)->rp_u.digest_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_DIGEST; \
|
||||
(req)->rp_optype = ftype; \
|
||||
dops->do_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
dops->do_mech = *mechp; \
|
||||
dops->do_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
dops->do_digest_key = _key; \
|
||||
dops->do_data = _data; \
|
||||
dops->do_digest = _digest; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_MAC_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _mac, _templ) { \
|
||||
kcf_mac_ops_params_t *mops = &(req)->rp_u.mac_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_MAC; \
|
||||
(req)->rp_optype = ftype; \
|
||||
mops->mo_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
mops->mo_mech = *mechp; \
|
||||
mops->mo_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
mops->mo_key = _key; \
|
||||
mops->mo_data = _data; \
|
||||
mops->mo_mac = _mac; \
|
||||
mops->mo_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_ENCRYPT_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_plaintext, _ciphertext, _templ) { \
|
||||
kcf_encrypt_ops_params_t *cops = &(req)->rp_u.encrypt_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_ENCRYPT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cops->eo_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
cops->eo_mech = *mechp; \
|
||||
cops->eo_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
cops->eo_key = _key; \
|
||||
cops->eo_plaintext = _plaintext; \
|
||||
cops->eo_ciphertext = _ciphertext; \
|
||||
cops->eo_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_DECRYPT_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_ciphertext, _plaintext, _templ) { \
|
||||
kcf_decrypt_ops_params_t *cops = &(req)->rp_u.decrypt_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_DECRYPT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cops->dop_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
cops->dop_mech = *mechp; \
|
||||
cops->dop_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
cops->dop_key = _key; \
|
||||
cops->dop_ciphertext = _ciphertext; \
|
||||
cops->dop_plaintext = _plaintext; \
|
||||
cops->dop_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_SIGN_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _signature, _templ) { \
|
||||
kcf_sign_ops_params_t *sops = &(req)->rp_u.sign_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_SIGN; \
|
||||
(req)->rp_optype = ftype; \
|
||||
sops->so_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
sops->so_mech = *mechp; \
|
||||
sops->so_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
sops->so_key = _key; \
|
||||
sops->so_data = _data; \
|
||||
sops->so_signature = _signature; \
|
||||
sops->so_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_VERIFY_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _signature, _templ) { \
|
||||
kcf_verify_ops_params_t *vops = &(req)->rp_u.verify_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_VERIFY; \
|
||||
(req)->rp_optype = ftype; \
|
||||
vops->vo_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
vops->vo_mech = *mechp; \
|
||||
vops->vo_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
vops->vo_key = _key; \
|
||||
vops->vo_data = _data; \
|
||||
vops->vo_signature = _signature; \
|
||||
vops->vo_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(req, ftype, _sid, _encr_key, \
|
||||
_mac_key, _plaintext, _ciphertext, _mac, _encr_templ, _mac_templ) { \
|
||||
kcf_encrypt_mac_ops_params_t *cmops = &(req)->rp_u.encrypt_mac_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_ENCRYPT_MAC; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cmops->em_sid = _sid; \
|
||||
cmops->em_encr_key = _encr_key; \
|
||||
cmops->em_mac_key = _mac_key; \
|
||||
cmops->em_plaintext = _plaintext; \
|
||||
cmops->em_ciphertext = _ciphertext; \
|
||||
cmops->em_mac = _mac; \
|
||||
cmops->em_encr_templ = _encr_templ; \
|
||||
cmops->em_mac_templ = _mac_templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(req, ftype, _sid, _mac_key, \
|
||||
_decr_key, _ciphertext, _mac, _plaintext, _mac_templ, _decr_templ) { \
|
||||
kcf_mac_decrypt_ops_params_t *cmops = &(req)->rp_u.mac_decrypt_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_MAC_DECRYPT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cmops->md_sid = _sid; \
|
||||
cmops->md_mac_key = _mac_key; \
|
||||
cmops->md_decr_key = _decr_key; \
|
||||
cmops->md_ciphertext = _ciphertext; \
|
||||
cmops->md_mac = _mac; \
|
||||
cmops->md_plaintext = _plaintext; \
|
||||
cmops->md_mac_templ = _mac_templ; \
|
||||
cmops->md_decr_templ = _decr_templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_RANDOM_OPS_PARAMS(req, ftype, _sid, _buf, _buflen, \
|
||||
_est, _flags) { \
|
||||
kcf_random_number_ops_params_t *rops = \
|
||||
&(req)->rp_u.random_number_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_RANDOM; \
|
||||
(req)->rp_optype = ftype; \
|
||||
rops->rn_sid = _sid; \
|
||||
rops->rn_buf = _buf; \
|
||||
rops->rn_buflen = _buflen; \
|
||||
rops->rn_entropy_est = _est; \
|
||||
rops->rn_flags = _flags; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_SESSION_OPS_PARAMS(req, ftype, _sid_ptr, _sid, \
|
||||
_user_type, _pin, _pin_len, _pd) { \
|
||||
kcf_session_ops_params_t *sops = &(req)->rp_u.session_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_SESSION; \
|
||||
(req)->rp_optype = ftype; \
|
||||
sops->so_sid_ptr = _sid_ptr; \
|
||||
sops->so_sid = _sid; \
|
||||
sops->so_user_type = _user_type; \
|
||||
sops->so_pin = _pin; \
|
||||
sops->so_pin_len = _pin_len; \
|
||||
sops->so_pd = _pd; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_OBJECT_OPS_PARAMS(req, ftype, _sid, _object_id, \
|
||||
_template, _attribute_count, _object_id_ptr, _object_size, \
|
||||
_find_init_pp_ptr, _find_pp, _max_object_count, _object_count_ptr) { \
|
||||
kcf_object_ops_params_t *jops = &(req)->rp_u.object_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_OBJECT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
jops->oo_sid = _sid; \
|
||||
jops->oo_object_id = _object_id; \
|
||||
jops->oo_template = _template; \
|
||||
jops->oo_attribute_count = _attribute_count; \
|
||||
jops->oo_object_id_ptr = _object_id_ptr; \
|
||||
jops->oo_object_size = _object_size; \
|
||||
jops->oo_find_init_pp_ptr = _find_init_pp_ptr; \
|
||||
jops->oo_find_pp = _find_pp; \
|
||||
jops->oo_max_object_count = _max_object_count; \
|
||||
jops->oo_object_count_ptr = _object_count_ptr; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_KEY_OPS_PARAMS(req, ftype, _sid, _mech, _key_template, \
|
||||
_key_attribute_count, _key_object_id_ptr, _private_key_template, \
|
||||
_private_key_attribute_count, _private_key_object_id_ptr, \
|
||||
_key, _wrapped_key, _wrapped_key_len_ptr) { \
|
||||
kcf_key_ops_params_t *kops = &(req)->rp_u.key_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_KEY; \
|
||||
(req)->rp_optype = ftype; \
|
||||
kops->ko_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
kops->ko_mech = *mechp; \
|
||||
kops->ko_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
kops->ko_key_template = _key_template; \
|
||||
kops->ko_key_attribute_count = _key_attribute_count; \
|
||||
kops->ko_key_object_id_ptr = _key_object_id_ptr; \
|
||||
kops->ko_private_key_template = _private_key_template; \
|
||||
kops->ko_private_key_attribute_count = _private_key_attribute_count; \
|
||||
kops->ko_private_key_object_id_ptr = _private_key_object_id_ptr; \
|
||||
kops->ko_key = _key; \
|
||||
kops->ko_wrapped_key = _wrapped_key; \
|
||||
kops->ko_wrapped_key_len_ptr = _wrapped_key_len_ptr; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_PROVMGMT_OPS_PARAMS(req, ftype, _sid, _old_pin, \
|
||||
_old_pin_len, _pin, _pin_len, _label, _ext_info, _pd) { \
|
||||
kcf_provmgmt_ops_params_t *pops = &(req)->rp_u.provmgmt_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_PROVMGMT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
pops->po_sid = _sid; \
|
||||
pops->po_pin = _pin; \
|
||||
pops->po_pin_len = _pin_len; \
|
||||
pops->po_old_pin = _old_pin; \
|
||||
pops->po_old_pin_len = _old_pin_len; \
|
||||
pops->po_label = _label; \
|
||||
pops->po_ext_info = _ext_info; \
|
||||
pops->po_pd = _pd; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(req, ftype, _sid, _mech, \
|
||||
_key_template, _key_attribute_count, _private_key_template, \
|
||||
_private_key_attribute_count, _key, _out_template1, \
|
||||
_out_attribute_count1, _out_template2, _out_attribute_count2) { \
|
||||
kcf_key_ops_params_t *kops = &(req)->rp_u.key_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_NOSTORE_KEY; \
|
||||
(req)->rp_optype = ftype; \
|
||||
kops->ko_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
kops->ko_mech = *mechp; \
|
||||
kops->ko_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
kops->ko_key_template = _key_template; \
|
||||
kops->ko_key_attribute_count = _key_attribute_count; \
|
||||
kops->ko_key_object_id_ptr = NULL; \
|
||||
kops->ko_private_key_template = _private_key_template; \
|
||||
kops->ko_private_key_attribute_count = _private_key_attribute_count; \
|
||||
kops->ko_private_key_object_id_ptr = NULL; \
|
||||
kops->ko_key = _key; \
|
||||
kops->ko_wrapped_key = NULL; \
|
||||
kops->ko_wrapped_key_len_ptr = 0; \
|
||||
kops->ko_out_template1 = _out_template1; \
|
||||
kops->ko_out_template2 = _out_template2; \
|
||||
kops->ko_out_attribute_count1 = _out_attribute_count1; \
|
||||
kops->ko_out_attribute_count2 = _out_attribute_count2; \
|
||||
}
|
||||
|
||||
#define KCF_SET_PROVIDER_MECHNUM(fmtype, pd, mechp) \
|
||||
(mechp)->cm_type = \
|
||||
KCF_TO_PROV_MECHNUM(pd, fmtype);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_OPS_IMPL_H */
|
||||
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_SCHED_IMPL_H
|
||||
#define _SYS_CRYPTO_SCHED_IMPL_H
|
||||
|
||||
/*
|
||||
* Scheduler internal structures.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/api.h>
|
||||
#include <sys/crypto/spi.h>
|
||||
#include <sys/crypto/impl.h>
|
||||
#include <sys/crypto/common.h>
|
||||
#include <sys/crypto/ops_impl.h>
|
||||
|
||||
typedef void (kcf_func_t)(void *, int);
|
||||
|
||||
typedef enum kcf_req_status {
|
||||
REQ_ALLOCATED = 1,
|
||||
REQ_WAITING, /* At the framework level */
|
||||
REQ_INPROGRESS, /* At the provider level */
|
||||
REQ_DONE,
|
||||
REQ_CANCELED
|
||||
} kcf_req_status_t;
|
||||
|
||||
typedef enum kcf_call_type {
|
||||
CRYPTO_SYNCH = 1,
|
||||
CRYPTO_ASYNCH
|
||||
} kcf_call_type_t;
|
||||
|
||||
#define CHECK_RESTRICT(crq) (crq != NULL && \
|
||||
((crq)->cr_flag & CRYPTO_RESTRICTED))
|
||||
|
||||
#define CHECK_RESTRICT_FALSE B_FALSE
|
||||
|
||||
#define CHECK_FASTPATH(crq, pd) ((crq) == NULL || \
|
||||
!((crq)->cr_flag & CRYPTO_ALWAYS_QUEUE)) && \
|
||||
(pd)->pd_prov_type == CRYPTO_SW_PROVIDER
|
||||
|
||||
#define KCF_KMFLAG(crq) (((crq) == NULL) ? KM_SLEEP : KM_NOSLEEP)
|
||||
|
||||
/*
|
||||
* The framework keeps an internal handle to use in the adaptive
|
||||
* asynchronous case. This is the case when a client has the
|
||||
* CRYPTO_ALWAYS_QUEUE bit clear and a software provider is used for
|
||||
* the request. The request is completed in the context of the calling
|
||||
* thread and kernel memory must be allocated with KM_NOSLEEP.
|
||||
*
|
||||
* The framework passes a pointer to the handle in crypto_req_handle_t
|
||||
* argument when it calls the SPI of the software provider. The macros
|
||||
* KCF_RHNDL() and KCF_SWFP_RHNDL() are used to do this.
|
||||
*
|
||||
* When a provider asks the framework for kmflag value via
|
||||
* crypto_kmflag(9S) we use REQHNDL2_KMFLAG() macro.
|
||||
*/
|
||||
extern ulong_t kcf_swprov_hndl;
|
||||
#define KCF_RHNDL(kmflag) (((kmflag) == KM_SLEEP) ? NULL : &kcf_swprov_hndl)
|
||||
#define KCF_SWFP_RHNDL(crq) (((crq) == NULL) ? NULL : &kcf_swprov_hndl)
|
||||
#define REQHNDL2_KMFLAG(rhndl) \
|
||||
((rhndl == &kcf_swprov_hndl) ? KM_NOSLEEP : KM_SLEEP)
|
||||
|
||||
/* Internal call_req flags. They start after the public ones in api.h */
|
||||
|
||||
#define CRYPTO_SETDUAL 0x00001000 /* Set the 'cont' boolean before */
|
||||
/* submitting the request */
|
||||
#define KCF_ISDUALREQ(crq) \
|
||||
(((crq) == NULL) ? B_FALSE : (crq->cr_flag & CRYPTO_SETDUAL))
|
||||
|
||||
typedef struct kcf_prov_tried {
|
||||
kcf_provider_desc_t *pt_pd;
|
||||
struct kcf_prov_tried *pt_next;
|
||||
} kcf_prov_tried_t;
|
||||
|
||||
#define IS_FG_SUPPORTED(mdesc, fg) \
|
||||
(((mdesc)->pm_mech_info.cm_func_group_mask & (fg)) != 0)
|
||||
|
||||
#define IS_PROVIDER_TRIED(pd, tlist) \
|
||||
(tlist != NULL && is_in_triedlist(pd, tlist))
|
||||
|
||||
#define IS_RECOVERABLE(error) \
|
||||
(error == CRYPTO_BUFFER_TOO_BIG || \
|
||||
error == CRYPTO_BUSY || \
|
||||
error == CRYPTO_DEVICE_ERROR || \
|
||||
error == CRYPTO_DEVICE_MEMORY || \
|
||||
error == CRYPTO_KEY_SIZE_RANGE || \
|
||||
error == CRYPTO_NO_PERMISSION)
|
||||
|
||||
#define KCF_ATOMIC_INCR(x) atomic_add_32(&(x), 1)
|
||||
#define KCF_ATOMIC_DECR(x) atomic_add_32(&(x), -1)
|
||||
|
||||
/*
|
||||
* Node structure for synchronous requests.
|
||||
*/
|
||||
typedef struct kcf_sreq_node {
|
||||
/* Should always be the first field in this structure */
|
||||
kcf_call_type_t sn_type;
|
||||
/*
|
||||
* sn_cv and sr_lock are used to wait for the
|
||||
* operation to complete. sn_lock also protects
|
||||
* the sn_state field.
|
||||
*/
|
||||
kcondvar_t sn_cv;
|
||||
kmutex_t sn_lock;
|
||||
kcf_req_status_t sn_state;
|
||||
|
||||
/*
|
||||
* Return value from the operation. This will be
|
||||
* one of the CRYPTO_* errors defined in common.h.
|
||||
*/
|
||||
int sn_rv;
|
||||
|
||||
/*
|
||||
* parameters to call the SPI with. This can be
|
||||
* a pointer as we know the caller context/stack stays.
|
||||
*/
|
||||
struct kcf_req_params *sn_params;
|
||||
|
||||
/* Internal context for this request */
|
||||
struct kcf_context *sn_context;
|
||||
|
||||
/* Provider handling this request */
|
||||
kcf_provider_desc_t *sn_provider;
|
||||
} kcf_sreq_node_t;
|
||||
|
||||
/*
|
||||
* Node structure for asynchronous requests. A node can be on
|
||||
* on a chain of requests hanging of the internal context
|
||||
* structure and can be in the global software provider queue.
|
||||
*/
|
||||
typedef struct kcf_areq_node {
|
||||
/* Should always be the first field in this structure */
|
||||
kcf_call_type_t an_type;
|
||||
|
||||
/* an_lock protects the field an_state */
|
||||
kmutex_t an_lock;
|
||||
kcf_req_status_t an_state;
|
||||
crypto_call_req_t an_reqarg;
|
||||
|
||||
/*
|
||||
* parameters to call the SPI with. We need to
|
||||
* save the params since the caller stack can go away.
|
||||
*/
|
||||
struct kcf_req_params an_params;
|
||||
|
||||
/*
|
||||
* The next two fields should be NULL for operations that
|
||||
* don't need a context.
|
||||
*/
|
||||
/* Internal context for this request */
|
||||
struct kcf_context *an_context;
|
||||
|
||||
/* next in chain of requests for context */
|
||||
struct kcf_areq_node *an_ctxchain_next;
|
||||
|
||||
kcondvar_t an_turn_cv;
|
||||
boolean_t an_is_my_turn;
|
||||
boolean_t an_isdual; /* for internal reuse */
|
||||
|
||||
/*
|
||||
* Next and previous nodes in the global software
|
||||
* queue. These fields are NULL for a hardware
|
||||
* provider since we use a taskq there.
|
||||
*/
|
||||
struct kcf_areq_node *an_next;
|
||||
struct kcf_areq_node *an_prev;
|
||||
|
||||
/* Provider handling this request */
|
||||
kcf_provider_desc_t *an_provider;
|
||||
kcf_prov_tried_t *an_tried_plist;
|
||||
|
||||
struct kcf_areq_node *an_idnext; /* Next in ID hash */
|
||||
struct kcf_areq_node *an_idprev; /* Prev in ID hash */
|
||||
kcondvar_t an_done; /* Signal request completion */
|
||||
uint_t an_refcnt;
|
||||
} kcf_areq_node_t;
|
||||
|
||||
#define KCF_AREQ_REFHOLD(areq) { \
|
||||
atomic_add_32(&(areq)->an_refcnt, 1); \
|
||||
ASSERT((areq)->an_refcnt != 0); \
|
||||
}
|
||||
|
||||
#define KCF_AREQ_REFRELE(areq) { \
|
||||
ASSERT((areq)->an_refcnt != 0); \
|
||||
membar_exit(); \
|
||||
if (atomic_add_32_nv(&(areq)->an_refcnt, -1) == 0) \
|
||||
kcf_free_req(areq); \
|
||||
}
|
||||
|
||||
#define GET_REQ_TYPE(arg) *((kcf_call_type_t *)(arg))
|
||||
|
||||
#define NOTIFY_CLIENT(areq, err) (*(areq)->an_reqarg.cr_callback_func)(\
|
||||
(areq)->an_reqarg.cr_callback_arg, err);
|
||||
|
||||
/* For internally generated call requests for dual operations */
|
||||
typedef struct kcf_call_req {
|
||||
crypto_call_req_t kr_callreq; /* external client call req */
|
||||
kcf_req_params_t kr_params; /* Params saved for next call */
|
||||
kcf_areq_node_t *kr_areq; /* Use this areq */
|
||||
off_t kr_saveoffset;
|
||||
size_t kr_savelen;
|
||||
} kcf_dual_req_t;
|
||||
|
||||
/*
|
||||
* The following are some what similar to macros in callo.h, which implement
|
||||
* callout tables.
|
||||
*
|
||||
* The lower four bits of the ID are used to encode the table ID to
|
||||
* index in to. The REQID_COUNTER_HIGH bit is used to avoid any check for
|
||||
* wrap around when generating ID. We assume that there won't be a request
|
||||
* which takes more time than 2^^(sizeof (long) - 5) other requests submitted
|
||||
* after it. This ensures there won't be any ID collision.
|
||||
*/
|
||||
#define REQID_COUNTER_HIGH (1UL << (8 * sizeof (long) - 1))
|
||||
#define REQID_COUNTER_SHIFT 4
|
||||
#define REQID_COUNTER_LOW (1 << REQID_COUNTER_SHIFT)
|
||||
#define REQID_TABLES 16
|
||||
#define REQID_TABLE_MASK (REQID_TABLES - 1)
|
||||
|
||||
#define REQID_BUCKETS 512
|
||||
#define REQID_BUCKET_MASK (REQID_BUCKETS - 1)
|
||||
#define REQID_HASH(id) (((id) >> REQID_COUNTER_SHIFT) & REQID_BUCKET_MASK)
|
||||
|
||||
#define GET_REQID(areq) (areq)->an_reqarg.cr_reqid
|
||||
#define SET_REQID(areq, val) GET_REQID(areq) = val
|
||||
|
||||
/*
|
||||
* Hash table for async requests.
|
||||
*/
|
||||
typedef struct kcf_reqid_table {
|
||||
kmutex_t rt_lock;
|
||||
crypto_req_id_t rt_curid;
|
||||
kcf_areq_node_t *rt_idhash[REQID_BUCKETS];
|
||||
} kcf_reqid_table_t;
|
||||
|
||||
/*
|
||||
* Global software provider queue structure. Requests to be
|
||||
* handled by a SW provider and have the ALWAYS_QUEUE flag set
|
||||
* get queued here.
|
||||
*/
|
||||
typedef struct kcf_global_swq {
|
||||
/*
|
||||
* gs_cv and gs_lock are used to wait for new requests.
|
||||
* gs_lock protects the changes to the queue.
|
||||
*/
|
||||
kcondvar_t gs_cv;
|
||||
kmutex_t gs_lock;
|
||||
uint_t gs_njobs;
|
||||
uint_t gs_maxjobs;
|
||||
kcf_areq_node_t *gs_first;
|
||||
kcf_areq_node_t *gs_last;
|
||||
} kcf_global_swq_t;
|
||||
|
||||
|
||||
/*
|
||||
* Internal representation of a canonical context. We contain crypto_ctx_t
|
||||
* structure in order to have just one memory allocation. The SPI
|
||||
* ((crypto_ctx_t *)ctx)->cc_framework_private maps to this structure.
|
||||
*/
|
||||
typedef struct kcf_context {
|
||||
crypto_ctx_t kc_glbl_ctx;
|
||||
uint_t kc_refcnt;
|
||||
kmutex_t kc_in_use_lock;
|
||||
/*
|
||||
* kc_req_chain_first and kc_req_chain_last are used to chain
|
||||
* multiple async requests using the same context. They should be
|
||||
* NULL for sync requests.
|
||||
*/
|
||||
kcf_areq_node_t *kc_req_chain_first;
|
||||
kcf_areq_node_t *kc_req_chain_last;
|
||||
kcf_provider_desc_t *kc_prov_desc; /* Prov. descriptor */
|
||||
kcf_provider_desc_t *kc_sw_prov_desc; /* Prov. descriptor */
|
||||
kcf_mech_entry_t *kc_mech;
|
||||
struct kcf_context *kc_secondctx; /* for dual contexts */
|
||||
} kcf_context_t;
|
||||
|
||||
/*
|
||||
* Bump up the reference count on the framework private context. A
|
||||
* global context or a request that references this structure should
|
||||
* do a hold.
|
||||
*/
|
||||
#define KCF_CONTEXT_REFHOLD(ictx) { \
|
||||
atomic_add_32(&(ictx)->kc_refcnt, 1); \
|
||||
ASSERT((ictx)->kc_refcnt != 0); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrement the reference count on the framework private context.
|
||||
* When the last reference is released, the framework private
|
||||
* context structure is freed along with the global context.
|
||||
*/
|
||||
#define KCF_CONTEXT_REFRELE(ictx) { \
|
||||
ASSERT((ictx)->kc_refcnt != 0); \
|
||||
membar_exit(); \
|
||||
if (atomic_add_32_nv(&(ictx)->kc_refcnt, -1) == 0) \
|
||||
kcf_free_context(ictx); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we can release the context now. In case of CRYPTO_QUEUED
|
||||
* we do not release it as we can do it only after the provider notified
|
||||
* us. In case of CRYPTO_BUSY, the client can retry the request using
|
||||
* the context, so we do not release the context.
|
||||
*
|
||||
* This macro should be called only from the final routine in
|
||||
* an init/update/final sequence. We do not release the context in case
|
||||
* of update operations. We require the consumer to free it
|
||||
* explicitly, in case it wants to abandon the operation. This is done
|
||||
* as there may be mechanisms in ECB mode that can continue even if
|
||||
* an operation on a block fails.
|
||||
*/
|
||||
#define KCF_CONTEXT_COND_RELEASE(rv, kcf_ctx) { \
|
||||
if (KCF_CONTEXT_DONE(rv)) \
|
||||
KCF_CONTEXT_REFRELE(kcf_ctx); \
|
||||
}
|
||||
|
||||
/*
|
||||
* This macro determines whether we're done with a context.
|
||||
*/
|
||||
#define KCF_CONTEXT_DONE(rv) \
|
||||
((rv) != CRYPTO_QUEUED && (rv) != CRYPTO_BUSY && \
|
||||
(rv) != CRYPTO_BUFFER_TOO_SMALL)
|
||||
|
||||
/*
|
||||
* A crypto_ctx_template_t is internally a pointer to this struct
|
||||
*/
|
||||
typedef struct kcf_ctx_template {
|
||||
crypto_kcf_provider_handle_t ct_prov_handle; /* provider handle */
|
||||
uint_t ct_generation; /* generation # */
|
||||
size_t ct_size; /* for freeing */
|
||||
crypto_spi_ctx_template_t ct_prov_tmpl; /* context template */
|
||||
/* from the SW prov */
|
||||
} kcf_ctx_template_t;
|
||||
|
||||
/*
|
||||
* Structure for pool of threads working on global software queue.
|
||||
*/
|
||||
typedef struct kcf_pool {
|
||||
uint32_t kp_threads; /* Number of threads in pool */
|
||||
uint32_t kp_idlethreads; /* Idle threads in pool */
|
||||
uint32_t kp_blockedthreads; /* Blocked threads in pool */
|
||||
|
||||
/*
|
||||
* cv & lock to monitor the condition when no threads
|
||||
* are around. In this case the failover thread kicks in.
|
||||
*/
|
||||
kcondvar_t kp_nothr_cv;
|
||||
kmutex_t kp_thread_lock;
|
||||
|
||||
/* Userspace thread creator variables. */
|
||||
boolean_t kp_signal_create_thread; /* Create requested flag */
|
||||
int kp_nthrs; /* # of threads to create */
|
||||
boolean_t kp_user_waiting; /* Thread waiting for work */
|
||||
|
||||
/*
|
||||
* cv & lock for the condition where more threads need to be
|
||||
* created. kp_user_lock also protects the three fileds above.
|
||||
*/
|
||||
kcondvar_t kp_user_cv; /* Creator cond. variable */
|
||||
kmutex_t kp_user_lock; /* Creator lock */
|
||||
} kcf_pool_t;
|
||||
|
||||
|
||||
/*
|
||||
* State of a crypto bufcall element.
|
||||
*/
|
||||
typedef enum cbuf_state {
|
||||
CBUF_FREE = 1,
|
||||
CBUF_WAITING,
|
||||
CBUF_RUNNING
|
||||
} cbuf_state_t;
|
||||
|
||||
/*
|
||||
* Structure of a crypto bufcall element.
|
||||
*/
|
||||
typedef struct kcf_cbuf_elem {
|
||||
/*
|
||||
* lock and cv to wait for CBUF_RUNNING to be done
|
||||
* kc_lock also protects kc_state.
|
||||
*/
|
||||
kmutex_t kc_lock;
|
||||
kcondvar_t kc_cv;
|
||||
cbuf_state_t kc_state;
|
||||
|
||||
struct kcf_cbuf_elem *kc_next;
|
||||
struct kcf_cbuf_elem *kc_prev;
|
||||
|
||||
void (*kc_func)(void *arg);
|
||||
void *kc_arg;
|
||||
} kcf_cbuf_elem_t;
|
||||
|
||||
/*
|
||||
* State of a notify element.
|
||||
*/
|
||||
typedef enum ntfy_elem_state {
|
||||
NTFY_WAITING = 1,
|
||||
NTFY_RUNNING
|
||||
} ntfy_elem_state_t;
|
||||
|
||||
/*
|
||||
* Structure of a notify list element.
|
||||
*/
|
||||
typedef struct kcf_ntfy_elem {
|
||||
/*
|
||||
* lock and cv to wait for NTFY_RUNNING to be done.
|
||||
* kn_lock also protects kn_state.
|
||||
*/
|
||||
kmutex_t kn_lock;
|
||||
kcondvar_t kn_cv;
|
||||
ntfy_elem_state_t kn_state;
|
||||
|
||||
struct kcf_ntfy_elem *kn_next;
|
||||
struct kcf_ntfy_elem *kn_prev;
|
||||
|
||||
crypto_notify_callback_t kn_func;
|
||||
uint32_t kn_event_mask;
|
||||
} kcf_ntfy_elem_t;
|
||||
|
||||
|
||||
/*
|
||||
* The following values are based on the assumption that it would
|
||||
* take around eight cpus to load a hardware provider (This is true for
|
||||
* at least one product) and a kernel client may come from different
|
||||
* low-priority interrupt levels. We will have CYRPTO_TASKQ_MIN number
|
||||
* of cached taskq entries. The CRYPTO_TASKQ_MAX number is based on
|
||||
* a throughput of 1GB/s using 512-byte buffers. These are just
|
||||
* reasonable estimates and might need to change in future.
|
||||
*/
|
||||
#define CRYPTO_TASKQ_THREADS 8
|
||||
#define CYRPTO_TASKQ_MIN 64
|
||||
#define CRYPTO_TASKQ_MAX 2 * 1024 * 1024
|
||||
|
||||
extern int crypto_taskq_threads;
|
||||
extern int crypto_taskq_minalloc;
|
||||
extern int crypto_taskq_maxalloc;
|
||||
extern kcf_global_swq_t *gswq;
|
||||
extern int kcf_maxthreads;
|
||||
extern int kcf_minthreads;
|
||||
|
||||
/*
|
||||
* All pending crypto bufcalls are put on a list. cbuf_list_lock
|
||||
* protects changes to this list.
|
||||
*/
|
||||
extern kmutex_t cbuf_list_lock;
|
||||
extern kcondvar_t cbuf_list_cv;
|
||||
|
||||
/*
|
||||
* All event subscribers are put on a list. kcf_notify_list_lock
|
||||
* protects changes to this list.
|
||||
*/
|
||||
extern kmutex_t ntfy_list_lock;
|
||||
extern kcondvar_t ntfy_list_cv;
|
||||
|
||||
boolean_t kcf_get_next_logical_provider_member(kcf_provider_desc_t *,
|
||||
kcf_provider_desc_t *, kcf_provider_desc_t **);
|
||||
extern int kcf_get_hardware_provider(crypto_mech_type_t, crypto_mech_type_t,
|
||||
boolean_t, kcf_provider_desc_t *, kcf_provider_desc_t **,
|
||||
crypto_func_group_t);
|
||||
extern int kcf_get_hardware_provider_nomech(offset_t, offset_t,
|
||||
boolean_t, kcf_provider_desc_t *, kcf_provider_desc_t **);
|
||||
extern void kcf_free_triedlist(kcf_prov_tried_t *);
|
||||
extern kcf_prov_tried_t *kcf_insert_triedlist(kcf_prov_tried_t **,
|
||||
kcf_provider_desc_t *, int);
|
||||
extern kcf_provider_desc_t *kcf_get_mech_provider(crypto_mech_type_t,
|
||||
kcf_mech_entry_t **, int *, kcf_prov_tried_t *, crypto_func_group_t,
|
||||
boolean_t, size_t);
|
||||
extern kcf_provider_desc_t *kcf_get_dual_provider(crypto_mechanism_t *,
|
||||
crypto_mechanism_t *, kcf_mech_entry_t **, crypto_mech_type_t *,
|
||||
crypto_mech_type_t *, int *, kcf_prov_tried_t *,
|
||||
crypto_func_group_t, crypto_func_group_t, boolean_t, size_t);
|
||||
extern crypto_ctx_t *kcf_new_ctx(crypto_call_req_t *, kcf_provider_desc_t *,
|
||||
crypto_session_id_t);
|
||||
extern int kcf_submit_request(kcf_provider_desc_t *, crypto_ctx_t *,
|
||||
crypto_call_req_t *, kcf_req_params_t *, boolean_t);
|
||||
extern void kcf_sched_destroy(void);
|
||||
extern void kcf_sched_init(void);
|
||||
extern void kcf_sched_start(void);
|
||||
extern void kcf_sop_done(kcf_sreq_node_t *, int);
|
||||
extern void kcf_aop_done(kcf_areq_node_t *, int);
|
||||
extern int common_submit_request(kcf_provider_desc_t *,
|
||||
crypto_ctx_t *, kcf_req_params_t *, crypto_req_handle_t);
|
||||
extern void kcf_free_context(kcf_context_t *);
|
||||
|
||||
extern int kcf_svc_wait(int *);
|
||||
extern int kcf_svc_do_run(void);
|
||||
extern int kcf_need_signature_verification(kcf_provider_desc_t *);
|
||||
extern void kcf_verify_signature(void *);
|
||||
extern struct modctl *kcf_get_modctl(crypto_provider_info_t *);
|
||||
extern void verify_unverified_providers(void);
|
||||
extern void kcf_free_req(kcf_areq_node_t *areq);
|
||||
extern void crypto_bufcall_service(void);
|
||||
|
||||
extern void kcf_walk_ntfylist(uint32_t, void *);
|
||||
extern void kcf_do_notify(kcf_provider_desc_t *, boolean_t);
|
||||
|
||||
extern kcf_dual_req_t *kcf_alloc_req(crypto_call_req_t *);
|
||||
extern void kcf_next_req(void *, int);
|
||||
extern void kcf_last_req(void *, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_SCHED_IMPL_H */
|
||||
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_SPI_H
|
||||
#define _SYS_CRYPTO_SPI_H
|
||||
|
||||
/*
|
||||
* CSPI: Cryptographic Service Provider Interface.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/common.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define CRYPTO_SPI_VERSION_1 1
|
||||
#define CRYPTO_SPI_VERSION_2 2
|
||||
#define CRYPTO_SPI_VERSION_3 3
|
||||
|
||||
/*
|
||||
* Provider-private handle. This handle is specified by a provider
|
||||
* when it registers by means of the pi_provider_handle field of
|
||||
* the crypto_provider_info structure, and passed to the provider
|
||||
* when its entry points are invoked.
|
||||
*/
|
||||
typedef void *crypto_provider_handle_t;
|
||||
|
||||
/*
|
||||
* Context templates can be used to by software providers to pre-process
|
||||
* keying material, such as key schedules. They are allocated by
|
||||
* a software provider create_ctx_template(9E) entry point, and passed
|
||||
* as argument to initialization and atomic provider entry points.
|
||||
*/
|
||||
typedef void *crypto_spi_ctx_template_t;
|
||||
|
||||
/*
|
||||
* Request handles are used by the kernel to identify an asynchronous
|
||||
* request being processed by a provider. It is passed by the kernel
|
||||
* to a hardware provider when submitting a request, and must be
|
||||
* specified by a provider when calling crypto_op_notification(9F)
|
||||
*/
|
||||
typedef void *crypto_req_handle_t;
|
||||
|
||||
/* Values for cc_flags field */
|
||||
#define CRYPTO_INIT_OPSTATE 0x00000001 /* allocate and init cc_opstate */
|
||||
#define CRYPTO_USE_OPSTATE 0x00000002 /* .. start using it as context */
|
||||
|
||||
/*
|
||||
* The context structure is passed from the kernel to a provider.
|
||||
* It contains the information needed to process a multi-part or
|
||||
* single part operation. The context structure is not used
|
||||
* by atomic operations.
|
||||
*
|
||||
* Parameters needed to perform a cryptographic operation, such
|
||||
* as keys, mechanisms, input and output buffers, are passed
|
||||
* as separate arguments to Provider routines.
|
||||
*/
|
||||
typedef struct crypto_ctx {
|
||||
crypto_provider_handle_t cc_provider;
|
||||
crypto_session_id_t cc_session;
|
||||
void *cc_provider_private; /* owned by provider */
|
||||
void *cc_framework_private; /* owned by framework */
|
||||
uint32_t cc_flags; /* flags */
|
||||
void *cc_opstate; /* state */
|
||||
} crypto_ctx_t;
|
||||
|
||||
/*
|
||||
* Extended provider information.
|
||||
*/
|
||||
|
||||
/*
|
||||
* valid values for ei_flags field of extended info structure
|
||||
* They match the RSA Security, Inc PKCS#11 tokenInfo flags.
|
||||
*/
|
||||
#define CRYPTO_EXTF_RNG 0x00000001
|
||||
#define CRYPTO_EXTF_WRITE_PROTECTED 0x00000002
|
||||
#define CRYPTO_EXTF_LOGIN_REQUIRED 0x00000004
|
||||
#define CRYPTO_EXTF_USER_PIN_INITIALIZED 0x00000008
|
||||
#define CRYPTO_EXTF_CLOCK_ON_TOKEN 0x00000040
|
||||
#define CRYPTO_EXTF_PROTECTED_AUTHENTICATION_PATH 0x00000100
|
||||
#define CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS 0x00000200
|
||||
#define CRYPTO_EXTF_TOKEN_INITIALIZED 0x00000400
|
||||
#define CRYPTO_EXTF_USER_PIN_COUNT_LOW 0x00010000
|
||||
#define CRYPTO_EXTF_USER_PIN_FINAL_TRY 0x00020000
|
||||
#define CRYPTO_EXTF_USER_PIN_LOCKED 0x00040000
|
||||
#define CRYPTO_EXTF_USER_PIN_TO_BE_CHANGED 0x00080000
|
||||
#define CRYPTO_EXTF_SO_PIN_COUNT_LOW 0x00100000
|
||||
#define CRYPTO_EXTF_SO_PIN_FINAL_TRY 0x00200000
|
||||
#define CRYPTO_EXTF_SO_PIN_LOCKED 0x00400000
|
||||
#define CRYPTO_EXTF_SO_PIN_TO_BE_CHANGED 0x00800000
|
||||
|
||||
/*
|
||||
* The crypto_control_ops structure contains pointers to control
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_control_ops {
|
||||
void (*provider_status)(crypto_provider_handle_t, uint_t *);
|
||||
} crypto_control_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_ctx_ops structure contains points to context and context
|
||||
* templates management operations for cryptographic providers. It is
|
||||
* passed through the crypto_ops(9S) structure when providers register
|
||||
* with the kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_ctx_ops {
|
||||
int (*create_ctx_template)(crypto_provider_handle_t,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t *, size_t *, crypto_req_handle_t);
|
||||
int (*free_context)(crypto_ctx_t *);
|
||||
} crypto_ctx_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_digest_ops structure contains pointers to digest
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_digest_ops {
|
||||
int (*digest_init)(crypto_ctx_t *, crypto_mechanism_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest)(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest_update)(crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest_key)(crypto_ctx_t *, crypto_key_t *, crypto_req_handle_t);
|
||||
int (*digest_final)(crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
} crypto_digest_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_cipher_ops structure contains pointers to encryption
|
||||
* and decryption operations for cryptographic providers. It is
|
||||
* passed through the crypto_ops(9S) structure when providers register
|
||||
* with the kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_cipher_ops {
|
||||
int (*encrypt_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*encrypt)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
|
||||
int (*decrypt_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*decrypt)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
} crypto_cipher_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_mac_ops structure contains pointers to MAC
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_mac_ops {
|
||||
int (*mac_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*mac)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*mac_verify_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_mac_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_sign_ops structure contains pointers to signing
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_sign_ops {
|
||||
int (*sign_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*sign)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*sign_recover_init)(crypto_ctx_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*sign_recover)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_recover_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_sign_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_verify_ops structure contains pointers to verify
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_verify_ops {
|
||||
int (*verify_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*do_verify)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*verify_recover_init)(crypto_ctx_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*verify_recover)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_recover_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_verify_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_dual_ops structure contains pointers to dual
|
||||
* cipher and sign/verify operations for cryptographic providers.
|
||||
* It is passed through the crypto_ops(9S) structure when
|
||||
* providers register with the kernel using
|
||||
* crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_dual_ops {
|
||||
int (*digest_encrypt_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_digest_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_encrypt_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_verify_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
} crypto_dual_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_dual_cipher_mac_ops structure contains pointers to dual
|
||||
* cipher and MAC operations for cryptographic providers.
|
||||
* It is passed through the crypto_ops(9S) structure when
|
||||
* providers register with the kernel using
|
||||
* crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_dual_cipher_mac_ops {
|
||||
int (*encrypt_mac_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*encrypt_mac)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*encrypt_mac_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_mac_final)(crypto_ctx_t *,
|
||||
crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_mac_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_data_t *, crypto_dual_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
|
||||
int (*mac_decrypt_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*mac_decrypt)(crypto_ctx_t *,
|
||||
crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*mac_decrypt_update)(crypto_ctx_t *,
|
||||
crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_decrypt_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_decrypt_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*mac_verify_decrypt_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
} crypto_dual_cipher_mac_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_random_number_ops structure contains pointers to random
|
||||
* number operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_random_number_ops {
|
||||
int (*seed_random)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
|
||||
int (*generate_random)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
uchar_t *, size_t, crypto_req_handle_t);
|
||||
} crypto_random_number_ops_t;
|
||||
|
||||
/*
|
||||
* Flag values for seed_random.
|
||||
*/
|
||||
#define CRYPTO_SEED_NOW 0x00000001
|
||||
|
||||
/*
|
||||
* The crypto_session_ops structure contains pointers to session
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_session_ops {
|
||||
int (*session_open)(crypto_provider_handle_t, crypto_session_id_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*session_close)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_req_handle_t);
|
||||
int (*session_login)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_user_type_t, char *, size_t, crypto_req_handle_t);
|
||||
int (*session_logout)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_session_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_object_ops structure contains pointers to object
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_object_ops {
|
||||
int (*object_create)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*object_copy)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_id_t, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*object_destroy)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_id_t, crypto_req_handle_t);
|
||||
int (*object_get_size)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_id_t, size_t *, crypto_req_handle_t);
|
||||
int (*object_get_attribute_value)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_object_id_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
int (*object_set_attribute_value)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_object_id_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
int (*object_find_init)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_attribute_t *, uint_t, void **,
|
||||
crypto_req_handle_t);
|
||||
int (*object_find)(crypto_provider_handle_t, void *,
|
||||
crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
|
||||
int (*object_find_final)(crypto_provider_handle_t, void *,
|
||||
crypto_req_handle_t);
|
||||
} crypto_object_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_key_ops structure contains pointers to key
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_key_ops {
|
||||
int (*key_generate)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_generate_pair)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_wrap)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
|
||||
uchar_t *, size_t *, crypto_req_handle_t);
|
||||
int (*key_unwrap)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
|
||||
crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_derive)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
|
||||
uint_t, crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_check)(crypto_provider_handle_t, crypto_mechanism_t *,
|
||||
crypto_key_t *);
|
||||
} crypto_key_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_provider_management_ops structure contains pointers
|
||||
* to management operations for cryptographic providers. It is passed
|
||||
* through the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_provider_management_ops {
|
||||
int (*ext_info)(crypto_provider_handle_t,
|
||||
crypto_provider_ext_info_t *, crypto_req_handle_t);
|
||||
int (*init_token)(crypto_provider_handle_t, char *, size_t,
|
||||
char *, crypto_req_handle_t);
|
||||
int (*init_pin)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
char *, size_t, crypto_req_handle_t);
|
||||
int (*set_pin)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
char *, size_t, char *, size_t, crypto_req_handle_t);
|
||||
} crypto_provider_management_ops_t;
|
||||
|
||||
typedef struct crypto_mech_ops {
|
||||
int (*copyin_mechanism)(crypto_provider_handle_t,
|
||||
crypto_mechanism_t *, crypto_mechanism_t *, int *, int);
|
||||
int (*copyout_mechanism)(crypto_provider_handle_t,
|
||||
crypto_mechanism_t *, crypto_mechanism_t *, int *, int);
|
||||
int (*free_mechanism)(crypto_provider_handle_t, crypto_mechanism_t *);
|
||||
} crypto_mech_ops_t;
|
||||
|
||||
typedef struct crypto_nostore_key_ops {
|
||||
int (*nostore_key_generate)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
|
||||
uint_t, crypto_req_handle_t);
|
||||
int (*nostore_key_generate_pair)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
|
||||
uint_t, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
int (*nostore_key_derive)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
|
||||
uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
} crypto_nostore_key_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_ops(9S) structure contains the structures containing
|
||||
* the pointers to functions implemented by cryptographic providers.
|
||||
* It is specified as part of the crypto_provider_info(9S)
|
||||
* supplied by a provider when it registers with the kernel
|
||||
* by calling crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_ops_v1 {
|
||||
crypto_control_ops_t *co_control_ops;
|
||||
crypto_digest_ops_t *co_digest_ops;
|
||||
crypto_cipher_ops_t *co_cipher_ops;
|
||||
crypto_mac_ops_t *co_mac_ops;
|
||||
crypto_sign_ops_t *co_sign_ops;
|
||||
crypto_verify_ops_t *co_verify_ops;
|
||||
crypto_dual_ops_t *co_dual_ops;
|
||||
crypto_dual_cipher_mac_ops_t *co_dual_cipher_mac_ops;
|
||||
crypto_random_number_ops_t *co_random_ops;
|
||||
crypto_session_ops_t *co_session_ops;
|
||||
crypto_object_ops_t *co_object_ops;
|
||||
crypto_key_ops_t *co_key_ops;
|
||||
crypto_provider_management_ops_t *co_provider_ops;
|
||||
crypto_ctx_ops_t *co_ctx_ops;
|
||||
} crypto_ops_v1_t;
|
||||
|
||||
typedef struct crypto_ops_v2 {
|
||||
crypto_ops_v1_t v1_ops;
|
||||
crypto_mech_ops_t *co_mech_ops;
|
||||
} crypto_ops_v2_t;
|
||||
|
||||
typedef struct crypto_ops_v3 {
|
||||
crypto_ops_v2_t v2_ops;
|
||||
crypto_nostore_key_ops_t *co_nostore_key_ops;
|
||||
} crypto_ops_v3_t;
|
||||
|
||||
typedef struct crypto_ops {
|
||||
union {
|
||||
crypto_ops_v3_t cou_v3;
|
||||
crypto_ops_v2_t cou_v2;
|
||||
crypto_ops_v1_t cou_v1;
|
||||
} cou;
|
||||
} crypto_ops_t;
|
||||
|
||||
#define co_control_ops cou.cou_v1.co_control_ops
|
||||
#define co_digest_ops cou.cou_v1.co_digest_ops
|
||||
#define co_cipher_ops cou.cou_v1.co_cipher_ops
|
||||
#define co_mac_ops cou.cou_v1.co_mac_ops
|
||||
#define co_sign_ops cou.cou_v1.co_sign_ops
|
||||
#define co_verify_ops cou.cou_v1.co_verify_ops
|
||||
#define co_dual_ops cou.cou_v1.co_dual_ops
|
||||
#define co_dual_cipher_mac_ops cou.cou_v1.co_dual_cipher_mac_ops
|
||||
#define co_random_ops cou.cou_v1.co_random_ops
|
||||
#define co_session_ops cou.cou_v1.co_session_ops
|
||||
#define co_object_ops cou.cou_v1.co_object_ops
|
||||
#define co_key_ops cou.cou_v1.co_key_ops
|
||||
#define co_provider_ops cou.cou_v1.co_provider_ops
|
||||
#define co_ctx_ops cou.cou_v1.co_ctx_ops
|
||||
#define co_mech_ops cou.cou_v2.co_mech_ops
|
||||
#define co_nostore_key_ops cou.cou_v3.co_nostore_key_ops
|
||||
|
||||
/*
|
||||
* The mechanism info structure crypto_mech_info_t contains a function group
|
||||
* bit mask cm_func_group_mask. This field, of type crypto_func_group_t,
|
||||
* specifies the provider entry point that can be used a particular
|
||||
* mechanism. The function group mask is a combination of the following values.
|
||||
*/
|
||||
|
||||
typedef uint32_t crypto_func_group_t;
|
||||
|
||||
|
||||
#define CRYPTO_FG_ENCRYPT 0x00000001 /* encrypt_init() */
|
||||
#define CRYPTO_FG_DECRYPT 0x00000002 /* decrypt_init() */
|
||||
#define CRYPTO_FG_DIGEST 0x00000004 /* digest_init() */
|
||||
#define CRYPTO_FG_SIGN 0x00000008 /* sign_init() */
|
||||
#define CRYPTO_FG_SIGN_RECOVER 0x00000010 /* sign_recover_init() */
|
||||
#define CRYPTO_FG_VERIFY 0x00000020 /* verify_init() */
|
||||
#define CRYPTO_FG_VERIFY_RECOVER 0x00000040 /* verify_recover_init() */
|
||||
#define CRYPTO_FG_GENERATE 0x00000080 /* key_generate() */
|
||||
#define CRYPTO_FG_GENERATE_KEY_PAIR 0x00000100 /* key_generate_pair() */
|
||||
#define CRYPTO_FG_WRAP 0x00000200 /* key_wrap() */
|
||||
#define CRYPTO_FG_UNWRAP 0x00000400 /* key_unwrap() */
|
||||
#define CRYPTO_FG_DERIVE 0x00000800 /* key_derive() */
|
||||
#define CRYPTO_FG_MAC 0x00001000 /* mac_init() */
|
||||
#define CRYPTO_FG_ENCRYPT_MAC 0x00002000 /* encrypt_mac_init() */
|
||||
#define CRYPTO_FG_MAC_DECRYPT 0x00004000 /* decrypt_mac_init() */
|
||||
#define CRYPTO_FG_ENCRYPT_ATOMIC 0x00008000 /* encrypt_atomic() */
|
||||
#define CRYPTO_FG_DECRYPT_ATOMIC 0x00010000 /* decrypt_atomic() */
|
||||
#define CRYPTO_FG_MAC_ATOMIC 0x00020000 /* mac_atomic() */
|
||||
#define CRYPTO_FG_DIGEST_ATOMIC 0x00040000 /* digest_atomic() */
|
||||
#define CRYPTO_FG_SIGN_ATOMIC 0x00080000 /* sign_atomic() */
|
||||
#define CRYPTO_FG_SIGN_RECOVER_ATOMIC 0x00100000 /* sign_recover_atomic() */
|
||||
#define CRYPTO_FG_VERIFY_ATOMIC 0x00200000 /* verify_atomic() */
|
||||
#define CRYPTO_FG_VERIFY_RECOVER_ATOMIC 0x00400000 /* verify_recover_atomic() */
|
||||
#define CRYPTO_FG_ENCRYPT_MAC_ATOMIC 0x00800000 /* encrypt_mac_atomic() */
|
||||
#define CRYPTO_FG_MAC_DECRYPT_ATOMIC 0x01000000 /* mac_decrypt_atomic() */
|
||||
#define CRYPTO_FG_RESERVED 0x80000000
|
||||
|
||||
/*
|
||||
* Maximum length of the pi_provider_description field of the
|
||||
* crypto_provider_info structure.
|
||||
*/
|
||||
#define CRYPTO_PROVIDER_DESCR_MAX_LEN 64
|
||||
|
||||
|
||||
/* Bit mask for all the simple operations */
|
||||
#define CRYPTO_FG_SIMPLEOP_MASK (CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | \
|
||||
CRYPTO_FG_DIGEST | CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | CRYPTO_FG_MAC | \
|
||||
CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_DECRYPT_ATOMIC | \
|
||||
CRYPTO_FG_MAC_ATOMIC | CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_SIGN_ATOMIC | \
|
||||
CRYPTO_FG_VERIFY_ATOMIC)
|
||||
|
||||
/* Bit mask for all the dual operations */
|
||||
#define CRYPTO_FG_MAC_CIPHER_MASK (CRYPTO_FG_ENCRYPT_MAC | \
|
||||
CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | \
|
||||
CRYPTO_FG_MAC_DECRYPT_ATOMIC)
|
||||
|
||||
/* Add other combos to CRYPTO_FG_DUAL_MASK */
|
||||
#define CRYPTO_FG_DUAL_MASK CRYPTO_FG_MAC_CIPHER_MASK
|
||||
|
||||
/*
|
||||
* The crypto_mech_info structure specifies one of the mechanisms
|
||||
* supported by a cryptographic provider. The pi_mechanisms field of
|
||||
* the crypto_provider_info structure contains a pointer to an array
|
||||
* of crypto_mech_info's.
|
||||
*/
|
||||
typedef struct crypto_mech_info {
|
||||
crypto_mech_name_t cm_mech_name;
|
||||
crypto_mech_type_t cm_mech_number;
|
||||
crypto_func_group_t cm_func_group_mask;
|
||||
ssize_t cm_min_key_length;
|
||||
ssize_t cm_max_key_length;
|
||||
uint32_t cm_mech_flags;
|
||||
} crypto_mech_info_t;
|
||||
|
||||
/* Alias the old name to the new name for compatibility. */
|
||||
#define cm_keysize_unit cm_mech_flags
|
||||
|
||||
/*
|
||||
* The following is used by a provider that sets
|
||||
* CRYPTO_HASH_NO_UPDATE. It needs to specify the maximum
|
||||
* input data size it can digest in this field.
|
||||
*/
|
||||
#define cm_max_input_length cm_max_key_length
|
||||
|
||||
/*
|
||||
* crypto_kcf_provider_handle_t is a handle allocated by the kernel.
|
||||
* It is returned after the provider registers with
|
||||
* crypto_register_provider(), and must be specified by the provider
|
||||
* when calling crypto_unregister_provider(), and
|
||||
* crypto_provider_notification().
|
||||
*/
|
||||
typedef uint_t crypto_kcf_provider_handle_t;
|
||||
|
||||
/*
|
||||
* Provider information. Passed as argument to crypto_register_provider(9F).
|
||||
* Describes the provider and its capabilities. Multiple providers can
|
||||
* register for the same device instance. In this case, the same
|
||||
* pi_provider_dev must be specified with a different pi_provider_handle.
|
||||
*/
|
||||
typedef struct crypto_provider_info_v1 {
|
||||
uint_t pi_interface_version;
|
||||
char *pi_provider_description;
|
||||
crypto_provider_type_t pi_provider_type;
|
||||
crypto_provider_handle_t pi_provider_handle;
|
||||
crypto_ops_t *pi_ops_vector;
|
||||
uint_t pi_mech_list_count;
|
||||
crypto_mech_info_t *pi_mechanisms;
|
||||
uint_t pi_logical_provider_count;
|
||||
crypto_kcf_provider_handle_t *pi_logical_providers;
|
||||
} crypto_provider_info_v1_t;
|
||||
|
||||
typedef struct crypto_provider_info_v2 {
|
||||
crypto_provider_info_v1_t v1_info;
|
||||
uint_t pi_flags;
|
||||
} crypto_provider_info_v2_t;
|
||||
|
||||
typedef struct crypto_provider_info {
|
||||
union {
|
||||
crypto_provider_info_v2_t piu_v2;
|
||||
crypto_provider_info_v1_t piu_v1;
|
||||
} piu;
|
||||
} crypto_provider_info_t;
|
||||
|
||||
#define pi_interface_version piu.piu_v1.pi_interface_version
|
||||
#define pi_provider_description piu.piu_v1.pi_provider_description
|
||||
#define pi_provider_type piu.piu_v1.pi_provider_type
|
||||
#define pi_provider_handle piu.piu_v1.pi_provider_handle
|
||||
#define pi_ops_vector piu.piu_v1.pi_ops_vector
|
||||
#define pi_mech_list_count piu.piu_v1.pi_mech_list_count
|
||||
#define pi_mechanisms piu.piu_v1.pi_mechanisms
|
||||
#define pi_logical_provider_count piu.piu_v1.pi_logical_provider_count
|
||||
#define pi_logical_providers piu.piu_v1.pi_logical_providers
|
||||
#define pi_flags piu.piu_v2.pi_flags
|
||||
|
||||
/* hidden providers can only be accessed via a logical provider */
|
||||
#define CRYPTO_HIDE_PROVIDER 0x00000001
|
||||
/*
|
||||
* provider can not do multi-part digest (updates) and has a limit
|
||||
* on maximum input data that it can digest.
|
||||
*/
|
||||
#define CRYPTO_HASH_NO_UPDATE 0x00000002
|
||||
|
||||
/* provider can handle the request without returning a CRYPTO_QUEUED */
|
||||
#define CRYPTO_SYNCHRONOUS 0x00000004
|
||||
|
||||
#define CRYPTO_PIFLAGS_RESERVED2 0x40000000
|
||||
#define CRYPTO_PIFLAGS_RESERVED1 0x80000000
|
||||
|
||||
/*
|
||||
* Provider status passed by a provider to crypto_provider_notification(9F)
|
||||
* and returned by the provider_stauts(9E) entry point.
|
||||
*/
|
||||
#define CRYPTO_PROVIDER_READY 0
|
||||
#define CRYPTO_PROVIDER_BUSY 1
|
||||
#define CRYPTO_PROVIDER_FAILED 2
|
||||
|
||||
/*
|
||||
* Functions exported by Solaris to cryptographic providers. Providers
|
||||
* call these functions to register and unregister, notify the kernel
|
||||
* of state changes, and notify the kernel when a asynchronous request
|
||||
* completed.
|
||||
*/
|
||||
extern int crypto_register_provider(crypto_provider_info_t *,
|
||||
crypto_kcf_provider_handle_t *);
|
||||
extern int crypto_unregister_provider(crypto_kcf_provider_handle_t);
|
||||
extern void crypto_provider_notification(crypto_kcf_provider_handle_t, uint_t);
|
||||
extern void crypto_op_notification(crypto_req_handle_t, int);
|
||||
extern int crypto_kmflag(crypto_req_handle_t);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_SPI_H */
|
||||
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _IA32_SYS_ASM_LINKAGE_H
|
||||
#define _IA32_SYS_ASM_LINKAGE_H
|
||||
|
||||
#include <sys/stack.h>
|
||||
#include <sys/trap.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _ASM /* The remainder of this file is only for assembly files */
|
||||
|
||||
/*
|
||||
* make annoying differences in assembler syntax go away
|
||||
*/
|
||||
|
||||
/*
|
||||
* D16 and A16 are used to insert instructions prefixes; the
|
||||
* macros help the assembler code be slightly more portable.
|
||||
*/
|
||||
#if !defined(__GNUC_AS__)
|
||||
/*
|
||||
* /usr/ccs/bin/as prefixes are parsed as separate instructions
|
||||
*/
|
||||
#define D16 data16;
|
||||
#define A16 addr16;
|
||||
|
||||
/*
|
||||
* (There are some weird constructs in constant expressions)
|
||||
*/
|
||||
#define _CONST(const) [const]
|
||||
#define _BITNOT(const) -1!_CONST(const)
|
||||
#define _MUL(a, b) _CONST(a \* b)
|
||||
|
||||
#else
|
||||
/*
|
||||
* Why not use the 'data16' and 'addr16' prefixes .. well, the
|
||||
* assembler doesn't quite believe in real mode, and thus argues with
|
||||
* us about what we're trying to do.
|
||||
*/
|
||||
#define D16 .byte 0x66;
|
||||
#define A16 .byte 0x67;
|
||||
|
||||
#define _CONST(const) (const)
|
||||
#define _BITNOT(const) ~_CONST(const)
|
||||
#define _MUL(a, b) _CONST(a * b)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* C pointers are different sizes between i386 and amd64.
|
||||
* These constants can be used to compute offsets into pointer arrays.
|
||||
*/
|
||||
#if defined(__amd64)
|
||||
#define CLONGSHIFT 3
|
||||
#define CLONGSIZE 8
|
||||
#define CLONGMASK 7
|
||||
#elif defined(__i386)
|
||||
#define CLONGSHIFT 2
|
||||
#define CLONGSIZE 4
|
||||
#define CLONGMASK 3
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Since we know we're either ILP32 or LP64 ..
|
||||
*/
|
||||
#define CPTRSHIFT CLONGSHIFT
|
||||
#define CPTRSIZE CLONGSIZE
|
||||
#define CPTRMASK CLONGMASK
|
||||
|
||||
#if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT)
|
||||
#error "inconsistent shift constants"
|
||||
#endif
|
||||
|
||||
#if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1)
|
||||
#error "inconsistent mask constants"
|
||||
#endif
|
||||
|
||||
#define ASM_ENTRY_ALIGN 16
|
||||
|
||||
/*
|
||||
* SSE register alignment and save areas
|
||||
*/
|
||||
|
||||
#define XMM_SIZE 16
|
||||
#define XMM_ALIGN 16
|
||||
|
||||
#if defined(__amd64)
|
||||
|
||||
#define SAVE_XMM_PROLOG(sreg, nreg) \
|
||||
subq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp; \
|
||||
movq %rsp, sreg
|
||||
|
||||
#define RSTOR_XMM_EPILOG(sreg, nreg) \
|
||||
addq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp
|
||||
|
||||
#elif defined(__i386)
|
||||
|
||||
#define SAVE_XMM_PROLOG(sreg, nreg) \
|
||||
subl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; \
|
||||
movl %esp, sreg; \
|
||||
addl $XMM_ALIGN, sreg; \
|
||||
andl $_BITNOT(XMM_ALIGN-1), sreg
|
||||
|
||||
#define RSTOR_XMM_EPILOG(sreg, nreg) \
|
||||
addl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp;
|
||||
|
||||
#endif /* __i386 */
|
||||
|
||||
/*
|
||||
* profiling causes definitions of the MCOUNT and RTMCOUNT
|
||||
* particular to the type
|
||||
*/
|
||||
#ifdef GPROF
|
||||
|
||||
#define MCOUNT(x) \
|
||||
pushl %ebp; \
|
||||
movl %esp, %ebp; \
|
||||
call _mcount; \
|
||||
popl %ebp
|
||||
|
||||
#endif /* GPROF */
|
||||
|
||||
#ifdef PROF
|
||||
|
||||
#define MCOUNT(x) \
|
||||
/* CSTYLED */ \
|
||||
.lcomm .L_/**/x/**/1, 4, 4; \
|
||||
pushl %ebp; \
|
||||
movl %esp, %ebp; \
|
||||
/* CSTYLED */ \
|
||||
movl $.L_/**/x/**/1, %edx; \
|
||||
call _mcount; \
|
||||
popl %ebp
|
||||
|
||||
#endif /* PROF */
|
||||
|
||||
/*
|
||||
* if we are not profiling, MCOUNT should be defined to nothing
|
||||
*/
|
||||
#if !defined(PROF) && !defined(GPROF)
|
||||
#define MCOUNT(x)
|
||||
#endif /* !defined(PROF) && !defined(GPROF) */
|
||||
|
||||
#define RTMCOUNT(x) MCOUNT(x)
|
||||
|
||||
/*
|
||||
* Macro to define weak symbol aliases. These are similar to the ANSI-C
|
||||
* #pragma weak _name = name
|
||||
* except a compiler can determine type. The assembler must be told. Hence,
|
||||
* the second parameter must be the type of the symbol (i.e.: function,...)
|
||||
*/
|
||||
#define ANSI_PRAGMA_WEAK(sym, stype) \
|
||||
/* CSTYLED */ \
|
||||
.weak _/**/sym; \
|
||||
/* CSTYLED */ \
|
||||
.type _/**/sym, @stype; \
|
||||
/* CSTYLED */ \
|
||||
_/**/sym = sym
|
||||
|
||||
/*
|
||||
* Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in:
|
||||
* #pragma weak sym1 = sym2
|
||||
*/
|
||||
#define ANSI_PRAGMA_WEAK2(sym1, sym2, stype) \
|
||||
.weak sym1; \
|
||||
.type sym1, @stype; \
|
||||
sym1 = sym2
|
||||
|
||||
/*
|
||||
* ENTRY provides the standard procedure entry code and an easy way to
|
||||
* insert the calls to mcount for profiling. ENTRY_NP is identical, but
|
||||
* never calls mcount.
|
||||
*/
|
||||
#define ENTRY(x) \
|
||||
.text; \
|
||||
.align ASM_ENTRY_ALIGN; \
|
||||
.globl x; \
|
||||
.type x, @function; \
|
||||
x: MCOUNT(x)
|
||||
|
||||
#define ENTRY_NP(x) \
|
||||
.text; \
|
||||
.align ASM_ENTRY_ALIGN; \
|
||||
.globl x; \
|
||||
.type x, @function; \
|
||||
x:
|
||||
|
||||
#define RTENTRY(x) \
|
||||
.text; \
|
||||
.align ASM_ENTRY_ALIGN; \
|
||||
.globl x; \
|
||||
.type x, @function; \
|
||||
x: RTMCOUNT(x)
|
||||
|
||||
/*
|
||||
* ENTRY2 is identical to ENTRY but provides two labels for the entry point.
|
||||
*/
|
||||
#define ENTRY2(x, y) \
|
||||
.text; \
|
||||
.align ASM_ENTRY_ALIGN; \
|
||||
.globl x, y; \
|
||||
.type x, @function; \
|
||||
.type y, @function; \
|
||||
/* CSTYLED */ \
|
||||
x: ; \
|
||||
y: MCOUNT(x)
|
||||
|
||||
#define ENTRY_NP2(x, y) \
|
||||
.text; \
|
||||
.align ASM_ENTRY_ALIGN; \
|
||||
.globl x, y; \
|
||||
.type x, @function; \
|
||||
.type y, @function; \
|
||||
/* CSTYLED */ \
|
||||
x: ; \
|
||||
y:
|
||||
|
||||
|
||||
/*
|
||||
* ALTENTRY provides for additional entry points.
|
||||
*/
|
||||
#define ALTENTRY(x) \
|
||||
.globl x; \
|
||||
.type x, @function; \
|
||||
x:
|
||||
|
||||
/*
|
||||
* DGDEF and DGDEF2 provide global data declarations.
|
||||
*
|
||||
* DGDEF provides a word aligned word of storage.
|
||||
*
|
||||
* DGDEF2 allocates "sz" bytes of storage with **NO** alignment. This
|
||||
* implies this macro is best used for byte arrays.
|
||||
*
|
||||
* DGDEF3 allocates "sz" bytes of storage with "algn" alignment.
|
||||
*/
|
||||
#define DGDEF2(name, sz) \
|
||||
.data; \
|
||||
.globl name; \
|
||||
.type name, @object; \
|
||||
.size name, sz; \
|
||||
name:
|
||||
|
||||
#define DGDEF3(name, sz, algn) \
|
||||
.data; \
|
||||
.align algn; \
|
||||
.globl name; \
|
||||
.type name, @object; \
|
||||
.size name, sz; \
|
||||
name:
|
||||
|
||||
#define DGDEF(name) DGDEF3(name, 4, 4)
|
||||
|
||||
/*
|
||||
* SET_SIZE trails a function and set the size for the ELF symbol table.
|
||||
*/
|
||||
#define SET_SIZE(x) \
|
||||
.size x, [.-x]
|
||||
|
||||
/*
|
||||
* NWORD provides native word value.
|
||||
*/
|
||||
#if defined(__amd64)
|
||||
|
||||
/*CSTYLED*/
|
||||
#define NWORD quad
|
||||
|
||||
#elif defined(__i386)
|
||||
|
||||
#define NWORD long
|
||||
|
||||
#endif /* __i386 */
|
||||
|
||||
#endif /* _ASM */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _IA32_SYS_ASM_LINKAGE_H */
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _IA32_SYS_STACK_H
|
||||
#define _IA32_SYS_STACK_H
|
||||
|
||||
#if !defined(_ASM)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In the x86 world, a stack frame looks like this:
|
||||
*
|
||||
* |--------------------------|
|
||||
* 4n+8(%ebp) ->| argument word n |
|
||||
* | ... | (Previous frame)
|
||||
* 8(%ebp) ->| argument word 0 |
|
||||
* |--------------------------|--------------------
|
||||
* 4(%ebp) ->| return address |
|
||||
* |--------------------------|
|
||||
* 0(%ebp) ->| previous %ebp (optional) |
|
||||
* |--------------------------|
|
||||
* -4(%ebp) ->| unspecified | (Current frame)
|
||||
* | ... |
|
||||
* 0(%esp) ->| variable size |
|
||||
* |--------------------------|
|
||||
*/
|
||||
|
||||
/*
|
||||
* Stack alignment macros.
|
||||
*/
|
||||
|
||||
#define STACK_ALIGN32 4
|
||||
#define STACK_ENTRY_ALIGN32 4
|
||||
#define STACK_BIAS32 0
|
||||
#define SA32(x) (((x)+(STACK_ALIGN32-1)) & ~(STACK_ALIGN32-1))
|
||||
#define STACK_RESERVE32 0
|
||||
#define MINFRAME32 0
|
||||
|
||||
#if defined(__amd64)
|
||||
|
||||
/*
|
||||
* In the amd64 world, a stack frame looks like this:
|
||||
*
|
||||
* |--------------------------|
|
||||
* 8n+16(%rbp)->| argument word n |
|
||||
* | ... | (Previous frame)
|
||||
* 16(%rbp) ->| argument word 0 |
|
||||
* |--------------------------|--------------------
|
||||
* 8(%rbp) ->| return address |
|
||||
* |--------------------------|
|
||||
* 0(%rbp) ->| previous %rbp |
|
||||
* |--------------------------|
|
||||
* -8(%rbp) ->| unspecified | (Current frame)
|
||||
* | ... |
|
||||
* 0(%rsp) ->| variable size |
|
||||
* |--------------------------|
|
||||
* -128(%rsp) ->| reserved for function |
|
||||
* |--------------------------|
|
||||
*
|
||||
* The end of the input argument area must be aligned on a 16-byte
|
||||
* boundary; i.e. (%rsp - 8) % 16 == 0 at function entry.
|
||||
*
|
||||
* The 128-byte location beyond %rsp is considered to be reserved for
|
||||
* functions and is NOT modified by signal handlers. It can be used
|
||||
* to store temporary data that is not needed across function calls.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Stack alignment macros.
|
||||
*/
|
||||
|
||||
#define STACK_ALIGN64 16
|
||||
#define STACK_ENTRY_ALIGN64 8
|
||||
#define STACK_BIAS64 0
|
||||
#define SA64(x) (((x)+(STACK_ALIGN64-1)) & ~(STACK_ALIGN64-1))
|
||||
#define STACK_RESERVE64 128
|
||||
#define MINFRAME64 0
|
||||
|
||||
#define STACK_ALIGN STACK_ALIGN64
|
||||
#define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN64
|
||||
#define STACK_BIAS STACK_BIAS64
|
||||
#define SA(x) SA64(x)
|
||||
#define STACK_RESERVE STACK_RESERVE64
|
||||
#define MINFRAME MINFRAME64
|
||||
|
||||
#elif defined(__i386)
|
||||
|
||||
#define STACK_ALIGN STACK_ALIGN32
|
||||
#define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN32
|
||||
#define STACK_BIAS STACK_BIAS32
|
||||
#define SA(x) SA32(x)
|
||||
#define STACK_RESERVE STACK_RESERVE32
|
||||
#define MINFRAME MINFRAME32
|
||||
|
||||
#endif /* __i386 */
|
||||
|
||||
#if defined(_KERNEL) && !defined(_ASM)
|
||||
|
||||
#if defined(DEBUG)
|
||||
#if STACK_ALIGN == 4
|
||||
#define ASSERT_STACK_ALIGNED() \
|
||||
{ \
|
||||
uint32_t __tmp; \
|
||||
ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \
|
||||
}
|
||||
#elif (STACK_ALIGN == 16) && (_LONG_DOUBLE_ALIGNMENT == 16)
|
||||
#define ASSERT_STACK_ALIGNED() \
|
||||
{ \
|
||||
long double __tmp; \
|
||||
ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \
|
||||
}
|
||||
#endif
|
||||
#else /* DEBUG */
|
||||
#define ASSERT_STACK_ALIGNED()
|
||||
#endif /* DEBUG */
|
||||
|
||||
struct regs;
|
||||
|
||||
void traceregs(struct regs *);
|
||||
void traceback(caddr_t);
|
||||
|
||||
#endif /* defined(_KERNEL) && !defined(_ASM) */
|
||||
|
||||
#define STACK_GROWTH_DOWN /* stacks grow from high to low addresses */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _IA32_SYS_STACK_H */
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 (c) 1990, 1991 UNIX System Laboratories, Inc. */
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _IA32_SYS_TRAP_H
|
||||
#define _IA32_SYS_TRAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Trap type values
|
||||
*/
|
||||
|
||||
#define T_ZERODIV 0x0 /* #de divide by 0 error */
|
||||
#define T_SGLSTP 0x1 /* #db single step */
|
||||
#define T_NMIFLT 0x2 /* NMI */
|
||||
#define T_BPTFLT 0x3 /* #bp breakpoint fault, INT3 insn */
|
||||
#define T_OVFLW 0x4 /* #of INTO overflow fault */
|
||||
#define T_BOUNDFLT 0x5 /* #br BOUND insn fault */
|
||||
#define T_ILLINST 0x6 /* #ud invalid opcode fault */
|
||||
#define T_NOEXTFLT 0x7 /* #nm device not available: x87 */
|
||||
#define T_DBLFLT 0x8 /* #df double fault */
|
||||
#define T_EXTOVRFLT 0x9 /* [not generated: 386 only] */
|
||||
#define T_TSSFLT 0xa /* #ts invalid TSS fault */
|
||||
#define T_SEGFLT 0xb /* #np segment not present fault */
|
||||
#define T_STKFLT 0xc /* #ss stack fault */
|
||||
#define T_GPFLT 0xd /* #gp general protection fault */
|
||||
#define T_PGFLT 0xe /* #pf page fault */
|
||||
#define T_EXTERRFLT 0x10 /* #mf x87 FPU error fault */
|
||||
#define T_ALIGNMENT 0x11 /* #ac alignment check error */
|
||||
#define T_MCE 0x12 /* #mc machine check exception */
|
||||
#define T_SIMDFPE 0x13 /* #xm SSE/SSE exception */
|
||||
#define T_DBGENTR 0x14 /* debugger entry */
|
||||
#define T_ENDPERR 0x21 /* emulated extension error flt */
|
||||
#define T_ENOEXTFLT 0x20 /* emulated ext not present */
|
||||
#define T_FASTTRAP 0xd2 /* fast system call */
|
||||
#define T_SYSCALLINT 0x91 /* general system call */
|
||||
#define T_DTRACE_RET 0x7f /* DTrace pid return */
|
||||
#define T_INT80 0x80 /* int80 handler for linux emulation */
|
||||
#define T_SOFTINT 0x50fd /* pseudo softint trap type */
|
||||
|
||||
/*
|
||||
* Pseudo traps.
|
||||
*/
|
||||
#define T_INTERRUPT 0x100
|
||||
#define T_FAULT 0x200
|
||||
#define T_AST 0x400
|
||||
#define T_SYSCALL 0x180
|
||||
|
||||
|
||||
/*
|
||||
* Values of error code on stack in case of page fault
|
||||
*/
|
||||
|
||||
#define PF_ERR_MASK 0x01 /* Mask for error bit */
|
||||
#define PF_ERR_PAGE 0x00 /* page not present */
|
||||
#define PF_ERR_PROT 0x01 /* protection error */
|
||||
#define PF_ERR_WRITE 0x02 /* fault caused by write (else read) */
|
||||
#define PF_ERR_USER 0x04 /* processor was in user mode */
|
||||
/* (else supervisor) */
|
||||
#define PF_ERR_EXEC 0x10 /* attempt to execute a No eXec page (AMD) */
|
||||
|
||||
/*
|
||||
* Definitions for fast system call subfunctions
|
||||
*/
|
||||
#define T_FNULL 0 /* Null trap for testing */
|
||||
#define T_FGETFP 1 /* Get emulated FP context */
|
||||
#define T_FSETFP 2 /* Set emulated FP context */
|
||||
#define T_GETHRTIME 3 /* Get high resolution time */
|
||||
#define T_GETHRVTIME 4 /* Get high resolution virtual time */
|
||||
#define T_GETHRESTIME 5 /* Get high resolution time */
|
||||
#define T_GETLGRP 6 /* Get home lgrpid */
|
||||
|
||||
#define T_LASTFAST 6 /* Last valid subfunction */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _IA32_SYS_TRAP_H */
|
||||
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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_MODCTL_H
|
||||
#define _SYS_MODCTL_H
|
||||
|
||||
/*
|
||||
* loadable module support.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct modlmisc;
|
||||
struct modlinkage;
|
||||
|
||||
/*
|
||||
* The following structure defines the operations used by modctl
|
||||
* to load and unload modules. Each supported loadable module type
|
||||
* requires a set of mod_ops.
|
||||
*/
|
||||
struct mod_ops {
|
||||
int (*modm_install)(struct modlmisc *, struct modlinkage *);
|
||||
int (*modm_remove)(struct modlmisc *, struct modlinkage *);
|
||||
int (*modm_info)(void *, struct modlinkage *, int *);
|
||||
};
|
||||
|
||||
/*
|
||||
* The defined set of mod_ops structures for each loadable module type
|
||||
* Defined in modctl.c
|
||||
*/
|
||||
extern struct mod_ops mod_brandops;
|
||||
#if defined(__i386) || defined(__amd64)
|
||||
extern struct mod_ops mod_cpuops;
|
||||
#endif
|
||||
extern struct mod_ops mod_cryptoops;
|
||||
extern struct mod_ops mod_driverops;
|
||||
extern struct mod_ops mod_execops;
|
||||
extern struct mod_ops mod_fsops;
|
||||
extern struct mod_ops mod_miscops;
|
||||
extern struct mod_ops mod_schedops;
|
||||
extern struct mod_ops mod_strmodops;
|
||||
extern struct mod_ops mod_syscallops;
|
||||
extern struct mod_ops mod_sockmodops;
|
||||
#ifdef _SYSCALL32_IMPL
|
||||
extern struct mod_ops mod_syscallops32;
|
||||
#endif
|
||||
extern struct mod_ops mod_dacfops;
|
||||
extern struct mod_ops mod_ippops;
|
||||
extern struct mod_ops mod_pcbeops;
|
||||
extern struct mod_ops mod_devfsops;
|
||||
extern struct mod_ops mod_kiconvops;
|
||||
|
||||
/*
|
||||
* Definitions for the module specific linkage structures.
|
||||
* The first two fields are the same in all of the structures.
|
||||
* The linkinfo is for informational purposes only and is returned by
|
||||
* modctl with the MODINFO cmd.
|
||||
*/
|
||||
|
||||
/* For cryptographic providers */
|
||||
struct modlcrypto {
|
||||
struct mod_ops *crypto_modops;
|
||||
char *crypto_linkinfo;
|
||||
};
|
||||
|
||||
/* For misc */
|
||||
struct modlmisc {
|
||||
struct mod_ops *misc_modops;
|
||||
char *misc_linkinfo;
|
||||
};
|
||||
|
||||
/*
|
||||
* Revision number of loadable modules support. This is the value
|
||||
* that must be used in the modlinkage structure.
|
||||
*/
|
||||
#define MODREV_1 1
|
||||
|
||||
/*
|
||||
* The modlinkage structure is the structure that the module writer
|
||||
* provides to the routines to install, remove, and stat a module.
|
||||
* The ml_linkage element is an array of pointers to linkage structures.
|
||||
* For most modules there is only one linkage structure. We allocate
|
||||
* enough space for 3 linkage structures which happens to be the most
|
||||
* we have in any sun supplied module. For those modules with more
|
||||
* than 3 linkage structures (which is very unlikely), a modlinkage
|
||||
* structure must be kmem_alloc'd in the module wrapper to be big enough
|
||||
* for all of the linkage structures.
|
||||
*/
|
||||
struct modlinkage {
|
||||
int ml_rev; /* rev of loadable modules system */
|
||||
#ifdef _LP64
|
||||
void *ml_linkage[7]; /* more space in 64-bit OS */
|
||||
#else
|
||||
void *ml_linkage[4]; /* NULL terminated list of */
|
||||
/* linkage structures */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* commands. These are the commands supported by the modctl system call.
|
||||
*/
|
||||
#define MODLOAD 0
|
||||
#define MODUNLOAD 1
|
||||
#define MODINFO 2
|
||||
#define MODRESERVED 3
|
||||
#define MODSETMINIROOT 4
|
||||
#define MODADDMAJBIND 5
|
||||
#define MODGETPATH 6
|
||||
#define MODREADSYSBIND 7
|
||||
#define MODGETMAJBIND 8
|
||||
#define MODGETNAME 9
|
||||
#define MODSIZEOF_DEVID 10
|
||||
#define MODGETDEVID 11
|
||||
#define MODSIZEOF_MINORNAME 12
|
||||
#define MODGETMINORNAME 13
|
||||
#define MODGETPATHLEN 14
|
||||
#define MODEVENTS 15
|
||||
#define MODGETFBNAME 16
|
||||
#define MODREREADDACF 17
|
||||
#define MODLOADDRVCONF 18
|
||||
#define MODUNLOADDRVCONF 19
|
||||
#define MODREMMAJBIND 20
|
||||
#define MODDEVT2INSTANCE 21
|
||||
#define MODGETDEVFSPATH_LEN 22
|
||||
#define MODGETDEVFSPATH 23
|
||||
#define MODDEVID2PATHS 24
|
||||
#define MODSETDEVPOLICY 26
|
||||
#define MODGETDEVPOLICY 27
|
||||
#define MODALLOCPRIV 28
|
||||
#define MODGETDEVPOLICYBYNAME 29
|
||||
#define MODLOADMINORPERM 31
|
||||
#define MODADDMINORPERM 32
|
||||
#define MODREMMINORPERM 33
|
||||
#define MODREMDRVCLEANUP 34
|
||||
#define MODDEVEXISTS 35
|
||||
#define MODDEVREADDIR 36
|
||||
#define MODDEVNAME 37
|
||||
#define MODGETDEVFSPATH_MI_LEN 38
|
||||
#define MODGETDEVFSPATH_MI 39
|
||||
#define MODRETIRE 40
|
||||
#define MODUNRETIRE 41
|
||||
#define MODISRETIRED 42
|
||||
#define MODDEVEMPTYDIR 43
|
||||
#define MODREMDRVALIAS 44
|
||||
|
||||
/*
|
||||
* sub cmds for MODEVENTS
|
||||
*/
|
||||
#define MODEVENTS_FLUSH 0
|
||||
#define MODEVENTS_FLUSH_DUMP 1
|
||||
#define MODEVENTS_SET_DOOR_UPCALL_FILENAME 2
|
||||
#define MODEVENTS_GETDATA 3
|
||||
#define MODEVENTS_FREEDATA 4
|
||||
#define MODEVENTS_POST_EVENT 5
|
||||
#define MODEVENTS_REGISTER_EVENT 6
|
||||
|
||||
/*
|
||||
* devname subcmds for MODDEVNAME
|
||||
*/
|
||||
#define MODDEVNAME_LOOKUPDOOR 0
|
||||
#define MODDEVNAME_DEVFSADMNODE 1
|
||||
#define MODDEVNAME_NSMAPS 2
|
||||
#define MODDEVNAME_PROFILE 3
|
||||
#define MODDEVNAME_RECONFIG 4
|
||||
#define MODDEVNAME_SYSAVAIL 5
|
||||
|
||||
|
||||
/*
|
||||
* Data structure passed to modconfig command in kernel to build devfs tree
|
||||
*/
|
||||
|
||||
struct aliases {
|
||||
struct aliases *a_next;
|
||||
char *a_name;
|
||||
int a_len;
|
||||
};
|
||||
|
||||
#define MAXMODCONFNAME 256
|
||||
|
||||
struct modconfig {
|
||||
char drvname[MAXMODCONFNAME];
|
||||
char drvclass[MAXMODCONFNAME];
|
||||
int major;
|
||||
int flags;
|
||||
int num_aliases;
|
||||
struct aliases *ap;
|
||||
};
|
||||
|
||||
#if defined(_SYSCALL32)
|
||||
|
||||
struct aliases32 {
|
||||
caddr32_t a_next;
|
||||
caddr32_t a_name;
|
||||
int32_t a_len;
|
||||
};
|
||||
|
||||
struct modconfig32 {
|
||||
char drvname[MAXMODCONFNAME];
|
||||
char drvclass[MAXMODCONFNAME];
|
||||
int32_t major;
|
||||
int32_t flags;
|
||||
int32_t num_aliases;
|
||||
caddr32_t ap;
|
||||
};
|
||||
|
||||
#endif /* _SYSCALL32 */
|
||||
|
||||
/* flags for modconfig */
|
||||
#define MOD_UNBIND_OVERRIDE 0x01 /* fail unbind if in use */
|
||||
|
||||
/*
|
||||
* Max module path length
|
||||
*/
|
||||
#define MOD_MAXPATH 256
|
||||
|
||||
/*
|
||||
* Default search path for modules ADDITIONAL to the directory
|
||||
* where the kernel components we booted from are.
|
||||
*
|
||||
* Most often, this will be "/platform/{platform}/kernel /kernel /usr/kernel",
|
||||
* but we don't wire it down here.
|
||||
*/
|
||||
#define MOD_DEFPATH "/kernel /usr/kernel"
|
||||
|
||||
/*
|
||||
* Default file name extension for autoloading modules.
|
||||
*/
|
||||
#define MOD_DEFEXT ""
|
||||
|
||||
/*
|
||||
* Parameters for modinfo
|
||||
*/
|
||||
#define MODMAXNAMELEN 32 /* max module name length */
|
||||
#define MODMAXLINKINFOLEN 32 /* max link info length */
|
||||
|
||||
/*
|
||||
* Module specific information.
|
||||
*/
|
||||
struct modspecific_info {
|
||||
char msi_linkinfo[MODMAXLINKINFOLEN]; /* name in linkage struct */
|
||||
int msi_p0; /* module specific information */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure returned by modctl with MODINFO command.
|
||||
*/
|
||||
#define MODMAXLINK 10 /* max linkages modinfo can handle */
|
||||
|
||||
struct modinfo {
|
||||
int mi_info; /* Flags for info wanted */
|
||||
int mi_state; /* Flags for module state */
|
||||
int mi_id; /* id of this loaded module */
|
||||
int mi_nextid; /* id of next module or -1 */
|
||||
caddr_t mi_base; /* virtual addr of text */
|
||||
size_t mi_size; /* size of module in bytes */
|
||||
int mi_rev; /* loadable modules rev */
|
||||
int mi_loadcnt; /* # of times loaded */
|
||||
char mi_name[MODMAXNAMELEN]; /* name of module */
|
||||
struct modspecific_info mi_msinfo[MODMAXLINK];
|
||||
/* mod specific info */
|
||||
};
|
||||
|
||||
|
||||
#if defined(_SYSCALL32)
|
||||
|
||||
#define MODMAXNAMELEN32 32 /* max module name length */
|
||||
#define MODMAXLINKINFOLEN32 32 /* max link info length */
|
||||
#define MODMAXLINK32 10 /* max linkages modinfo can handle */
|
||||
|
||||
struct modspecific_info32 {
|
||||
char msi_linkinfo[MODMAXLINKINFOLEN32]; /* name in linkage struct */
|
||||
int32_t msi_p0; /* module specific information */
|
||||
};
|
||||
|
||||
struct modinfo32 {
|
||||
int32_t mi_info; /* Flags for info wanted */
|
||||
int32_t mi_state; /* Flags for module state */
|
||||
int32_t mi_id; /* id of this loaded module */
|
||||
int32_t mi_nextid; /* id of next module or -1 */
|
||||
caddr32_t mi_base; /* virtual addr of text */
|
||||
uint32_t mi_size; /* size of module in bytes */
|
||||
int32_t mi_rev; /* loadable modules rev */
|
||||
int32_t mi_loadcnt; /* # of times loaded */
|
||||
char mi_name[MODMAXNAMELEN32]; /* name of module */
|
||||
struct modspecific_info32 mi_msinfo[MODMAXLINK32];
|
||||
/* mod specific info */
|
||||
};
|
||||
|
||||
#endif /* _SYSCALL32 */
|
||||
|
||||
/* Values for mi_info flags */
|
||||
#define MI_INFO_ONE 1
|
||||
#define MI_INFO_ALL 2
|
||||
#define MI_INFO_CNT 4
|
||||
#define MI_INFO_LINKAGE 8 /* used internally to extract modlinkage */
|
||||
/*
|
||||
* MI_INFO_NOBASE indicates caller does not need mi_base. Failure to use this
|
||||
* flag may lead 32-bit apps to receive an EOVERFLOW error from modctl(MODINFO)
|
||||
* when used with a 64-bit kernel.
|
||||
*/
|
||||
#define MI_INFO_NOBASE 16
|
||||
|
||||
/* Values for mi_state */
|
||||
#define MI_LOADED 1
|
||||
#define MI_INSTALLED 2
|
||||
|
||||
/*
|
||||
* Macros to vector to the appropriate module specific routine.
|
||||
*/
|
||||
#define MODL_INSTALL(MODL, MODLP) \
|
||||
(*(MODL)->misc_modops->modm_install)(MODL, MODLP)
|
||||
#define MODL_REMOVE(MODL, MODLP) \
|
||||
(*(MODL)->misc_modops->modm_remove)(MODL, MODLP)
|
||||
#define MODL_INFO(MODL, MODLP, P0) \
|
||||
(*(MODL)->misc_modops->modm_info)(MODL, MODLP, P0)
|
||||
|
||||
/*
|
||||
* Definitions for stubs
|
||||
*/
|
||||
struct mod_stub_info {
|
||||
uintptr_t mods_func_adr;
|
||||
struct mod_modinfo *mods_modinfo;
|
||||
uintptr_t mods_stub_adr;
|
||||
int (*mods_errfcn)(void);
|
||||
int mods_flag; /* flags defined below */
|
||||
};
|
||||
|
||||
/*
|
||||
* Definitions for mods_flag.
|
||||
*/
|
||||
#define MODS_WEAK 0x01 /* weak stub (not loaded if called) */
|
||||
#define MODS_NOUNLOAD 0x02 /* module not unloadable (no _fini()) */
|
||||
#define MODS_INSTALLED 0x10 /* module installed */
|
||||
|
||||
struct mod_modinfo {
|
||||
char *modm_module_name;
|
||||
struct modctl *mp;
|
||||
struct mod_stub_info modm_stubs[1];
|
||||
};
|
||||
|
||||
struct modctl_list {
|
||||
struct modctl_list *modl_next;
|
||||
struct modctl *modl_modp;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to manage a loadable module.
|
||||
* Note: the module (mod_mp) structure's "text" and "text_size" information
|
||||
* are replicated in the modctl structure so that mod_containing_pc()
|
||||
* doesn't have to grab any locks (modctls are persistent; modules are not.)
|
||||
*/
|
||||
typedef struct modctl {
|
||||
struct modctl *mod_next; /* &modules based list */
|
||||
struct modctl *mod_prev;
|
||||
int mod_id;
|
||||
void *mod_mp;
|
||||
kthread_t *mod_inprogress_thread;
|
||||
struct mod_modinfo *mod_modinfo;
|
||||
struct modlinkage *mod_linkage;
|
||||
char *mod_filename;
|
||||
char *mod_modname;
|
||||
|
||||
char mod_busy; /* inprogress_thread has locked */
|
||||
char mod_want; /* someone waiting for unlock */
|
||||
char mod_prim; /* primary module */
|
||||
|
||||
int mod_ref; /* ref count - from dependent or stub */
|
||||
|
||||
char mod_loaded; /* module in memory */
|
||||
char mod_installed; /* post _init pre _fini */
|
||||
char mod_loadflags;
|
||||
char mod_delay_unload; /* deferred unload */
|
||||
|
||||
struct modctl_list *mod_requisites; /* mods this one depends on. */
|
||||
void *__unused; /* NOTE: reuse (same size) is OK, */
|
||||
/* deletion causes mdb.vs.core issues */
|
||||
int mod_loadcnt; /* number of times mod was loaded */
|
||||
int mod_nenabled; /* # of enabled DTrace probes in mod */
|
||||
char *mod_text;
|
||||
size_t mod_text_size;
|
||||
|
||||
int mod_gencount; /* # times loaded/unloaded */
|
||||
struct modctl *mod_requisite_loading; /* mod circular dependency */
|
||||
} modctl_t;
|
||||
|
||||
/*
|
||||
* mod_loadflags
|
||||
*/
|
||||
|
||||
#define MOD_NOAUTOUNLOAD 0x1 /* Auto mod-unloader skips this mod */
|
||||
#define MOD_NONOTIFY 0x2 /* No krtld notifications on (un)load */
|
||||
#define MOD_NOUNLOAD 0x4 /* Assume EBUSY for all _fini's */
|
||||
|
||||
#define MOD_BIND_HASHSIZE 64
|
||||
#define MOD_BIND_HASHMASK (MOD_BIND_HASHSIZE-1)
|
||||
|
||||
typedef int modid_t;
|
||||
|
||||
/*
|
||||
* global function and data declarations
|
||||
*/
|
||||
extern kmutex_t mod_lock;
|
||||
|
||||
extern char *systemfile;
|
||||
extern char **syscallnames;
|
||||
extern int moddebug;
|
||||
|
||||
/*
|
||||
* this is the head of a doubly linked list. Only the next and prev
|
||||
* pointers are used
|
||||
*/
|
||||
extern modctl_t modules;
|
||||
|
||||
/*
|
||||
* Only the following are part of the DDI/DKI
|
||||
*/
|
||||
extern int mod_install(struct modlinkage *);
|
||||
extern int mod_remove(struct modlinkage *);
|
||||
extern int mod_info(struct modlinkage *, struct modinfo *);
|
||||
|
||||
/*
|
||||
* bit definitions for moddebug.
|
||||
*/
|
||||
#define MODDEBUG_LOADMSG 0x80000000 /* print "[un]loading..." msg */
|
||||
#define MODDEBUG_ERRMSG 0x40000000 /* print detailed error msgs */
|
||||
#define MODDEBUG_LOADMSG2 0x20000000 /* print 2nd level msgs */
|
||||
#define MODDEBUG_RETIRE 0x10000000 /* print retire msgs */
|
||||
#define MODDEBUG_BINDING 0x00040000 /* driver/alias binding */
|
||||
#define MODDEBUG_FINI_EBUSY 0x00020000 /* pretend fini returns EBUSY */
|
||||
#define MODDEBUG_NOAUL_IPP 0x00010000 /* no Autounloading ipp mods */
|
||||
#define MODDEBUG_NOAUL_DACF 0x00008000 /* no Autounloading dacf mods */
|
||||
#define MODDEBUG_KEEPTEXT 0x00004000 /* keep text after unloading */
|
||||
#define MODDEBUG_NOAUL_DRV 0x00001000 /* no Autounloading Drivers */
|
||||
#define MODDEBUG_NOAUL_EXEC 0x00000800 /* no Autounloading Execs */
|
||||
#define MODDEBUG_NOAUL_FS 0x00000400 /* no Autounloading File sys */
|
||||
#define MODDEBUG_NOAUL_MISC 0x00000200 /* no Autounloading misc */
|
||||
#define MODDEBUG_NOAUL_SCHED 0x00000100 /* no Autounloading scheds */
|
||||
#define MODDEBUG_NOAUL_STR 0x00000080 /* no Autounloading streams */
|
||||
#define MODDEBUG_NOAUL_SYS 0x00000040 /* no Autounloading syscalls */
|
||||
#define MODDEBUG_NOCTF 0x00000020 /* do not load CTF debug data */
|
||||
#define MODDEBUG_NOAUTOUNLOAD 0x00000010 /* no autounloading at all */
|
||||
#define MODDEBUG_DDI_MOD 0x00000008 /* ddi_mod{open,sym,close} */
|
||||
#define MODDEBUG_MP_MATCH 0x00000004 /* dev_minorperm */
|
||||
#define MODDEBUG_MINORPERM 0x00000002 /* minor perm modctls */
|
||||
#define MODDEBUG_USERDEBUG 0x00000001 /* bpt after init_module() */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_MODCTL_H */
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MODHASH_H
|
||||
#define _SYS_MODHASH_H
|
||||
|
||||
/*
|
||||
* Generic hash implementation for the kernel.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
/*
|
||||
* Opaque data types for storing keys and values
|
||||
*/
|
||||
typedef void *mod_hash_val_t;
|
||||
typedef void *mod_hash_key_t;
|
||||
|
||||
/*
|
||||
* Opaque data type for reservation
|
||||
*/
|
||||
typedef void *mod_hash_hndl_t;
|
||||
|
||||
/*
|
||||
* Opaque type for hash itself.
|
||||
*/
|
||||
struct mod_hash;
|
||||
typedef struct mod_hash mod_hash_t;
|
||||
|
||||
/*
|
||||
* String hash table
|
||||
*/
|
||||
mod_hash_t *mod_hash_create_strhash_nodtr(char *, size_t,
|
||||
void (*)(mod_hash_val_t));
|
||||
mod_hash_t *mod_hash_create_strhash(char *, size_t, void (*)(mod_hash_val_t));
|
||||
void mod_hash_destroy_strhash(mod_hash_t *);
|
||||
int mod_hash_strkey_cmp(mod_hash_key_t, mod_hash_key_t);
|
||||
void mod_hash_strkey_dtor(mod_hash_key_t);
|
||||
void mod_hash_strval_dtor(mod_hash_val_t);
|
||||
uint_t mod_hash_bystr(void *, mod_hash_key_t);
|
||||
|
||||
/*
|
||||
* Pointer hash table
|
||||
*/
|
||||
mod_hash_t *mod_hash_create_ptrhash(char *, size_t, void (*)(mod_hash_val_t),
|
||||
size_t);
|
||||
void mod_hash_destroy_ptrhash(mod_hash_t *);
|
||||
int mod_hash_ptrkey_cmp(mod_hash_key_t, mod_hash_key_t);
|
||||
uint_t mod_hash_byptr(void *, mod_hash_key_t);
|
||||
|
||||
/*
|
||||
* ID hash table
|
||||
*/
|
||||
mod_hash_t *mod_hash_create_idhash(char *, size_t, void (*)(mod_hash_val_t));
|
||||
void mod_hash_destroy_idhash(mod_hash_t *);
|
||||
int mod_hash_idkey_cmp(mod_hash_key_t, mod_hash_key_t);
|
||||
uint_t mod_hash_byid(void *, mod_hash_key_t);
|
||||
uint_t mod_hash_iddata_gen(size_t);
|
||||
|
||||
/*
|
||||
* Hash management functions
|
||||
*/
|
||||
mod_hash_t *mod_hash_create_extended(char *, size_t, void (*)(mod_hash_key_t),
|
||||
void (*)(mod_hash_val_t), uint_t (*)(void *, mod_hash_key_t), void *,
|
||||
int (*)(mod_hash_key_t, mod_hash_key_t), int);
|
||||
|
||||
void mod_hash_destroy_hash(mod_hash_t *);
|
||||
void mod_hash_clear(mod_hash_t *);
|
||||
|
||||
/*
|
||||
* Null key and value destructors
|
||||
*/
|
||||
void mod_hash_null_keydtor(mod_hash_key_t);
|
||||
void mod_hash_null_valdtor(mod_hash_val_t);
|
||||
|
||||
/*
|
||||
* Basic hash operations
|
||||
*/
|
||||
|
||||
/*
|
||||
* Error codes for insert, remove, find, destroy.
|
||||
*/
|
||||
#define MH_ERR_NOMEM -1
|
||||
#define MH_ERR_DUPLICATE -2
|
||||
#define MH_ERR_NOTFOUND -3
|
||||
|
||||
/*
|
||||
* Return codes for hash walkers
|
||||
*/
|
||||
#define MH_WALK_CONTINUE 0
|
||||
#define MH_WALK_TERMINATE 1
|
||||
|
||||
/*
|
||||
* Basic hash operations
|
||||
*/
|
||||
int mod_hash_insert(mod_hash_t *, mod_hash_key_t, mod_hash_val_t);
|
||||
int mod_hash_replace(mod_hash_t *, mod_hash_key_t, mod_hash_val_t);
|
||||
int mod_hash_remove(mod_hash_t *, mod_hash_key_t, mod_hash_val_t *);
|
||||
int mod_hash_destroy(mod_hash_t *, mod_hash_key_t);
|
||||
int mod_hash_find(mod_hash_t *, mod_hash_key_t, mod_hash_val_t *);
|
||||
int mod_hash_find_cb(mod_hash_t *, mod_hash_key_t, mod_hash_val_t *,
|
||||
void (*)(mod_hash_key_t, mod_hash_val_t));
|
||||
int mod_hash_find_cb_rval(mod_hash_t *, mod_hash_key_t, mod_hash_val_t *,
|
||||
int (*)(mod_hash_key_t, mod_hash_val_t), int *);
|
||||
void mod_hash_walk(mod_hash_t *,
|
||||
uint_t (*)(mod_hash_key_t, mod_hash_val_t *, void *), void *);
|
||||
|
||||
/*
|
||||
* Reserving hash operations
|
||||
*/
|
||||
int mod_hash_reserve(mod_hash_t *, mod_hash_hndl_t *);
|
||||
int mod_hash_reserve_nosleep(mod_hash_t *, mod_hash_hndl_t *);
|
||||
void mod_hash_cancel(mod_hash_t *, mod_hash_hndl_t *);
|
||||
int mod_hash_insert_reserve(mod_hash_t *, mod_hash_key_t, mod_hash_val_t,
|
||||
mod_hash_hndl_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_MODHASH_H */
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MODHASH_IMPL_H
|
||||
#define _SYS_MODHASH_IMPL_H
|
||||
|
||||
/*
|
||||
* Internal details for the kernel's generic hash implementation.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/modhash.h>
|
||||
|
||||
struct mod_hash_entry {
|
||||
mod_hash_key_t mhe_key; /* stored hash key */
|
||||
mod_hash_val_t mhe_val; /* stored hash value */
|
||||
struct mod_hash_entry *mhe_next; /* next item in chain */
|
||||
};
|
||||
|
||||
struct mod_hash_stat {
|
||||
ulong_t mhs_hit; /* tried a 'find' and it succeeded */
|
||||
ulong_t mhs_miss; /* tried a 'find' but it failed */
|
||||
ulong_t mhs_coll; /* occur when insert fails because of dup's */
|
||||
ulong_t mhs_nelems; /* total number of stored key/value pairs */
|
||||
ulong_t mhs_nomem; /* number of times kmem_alloc failed */
|
||||
};
|
||||
|
||||
struct mod_hash {
|
||||
krwlock_t mh_contents; /* lock protecting contents */
|
||||
char *mh_name; /* hash name */
|
||||
int mh_sleep; /* kmem_alloc flag */
|
||||
size_t mh_nchains; /* # of elements in mh_entries */
|
||||
|
||||
/* key and val destructor */
|
||||
void (*mh_kdtor)(mod_hash_key_t);
|
||||
void (*mh_vdtor)(mod_hash_val_t);
|
||||
|
||||
/* key comparator */
|
||||
int (*mh_keycmp)(mod_hash_key_t, mod_hash_key_t);
|
||||
|
||||
/* hash algorithm, and algorithm-private data */
|
||||
uint_t (*mh_hashalg)(void *, mod_hash_key_t);
|
||||
void *mh_hashalg_data;
|
||||
|
||||
struct mod_hash *mh_next; /* next hash in list */
|
||||
|
||||
struct mod_hash_stat mh_stat;
|
||||
|
||||
struct mod_hash_entry *mh_entries[1];
|
||||
};
|
||||
|
||||
/*
|
||||
* MH_SIZE()
|
||||
* Compute the size of a mod_hash_t, in bytes, given the number of
|
||||
* elements it contains.
|
||||
*/
|
||||
#define MH_SIZE(n) \
|
||||
(sizeof (mod_hash_t) + ((n) - 1) * (sizeof (struct mod_hash_entry *)))
|
||||
|
||||
/*
|
||||
* Module initialization; called once.
|
||||
*/
|
||||
void mod_hash_fini(void);
|
||||
void mod_hash_init(void);
|
||||
|
||||
/*
|
||||
* Internal routines. Use directly with care.
|
||||
*/
|
||||
uint_t i_mod_hash(mod_hash_t *, mod_hash_key_t);
|
||||
int i_mod_hash_insert_nosync(mod_hash_t *, mod_hash_key_t, mod_hash_val_t,
|
||||
mod_hash_hndl_t);
|
||||
int i_mod_hash_remove_nosync(mod_hash_t *, mod_hash_key_t, mod_hash_val_t *);
|
||||
int i_mod_hash_find_nosync(mod_hash_t *, mod_hash_key_t, mod_hash_val_t *);
|
||||
void i_mod_hash_walk_nosync(mod_hash_t *, uint_t (*)(mod_hash_key_t,
|
||||
mod_hash_val_t *, void *), void *);
|
||||
void i_mod_hash_clear_nosync(mod_hash_t *hash);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_MODHASH_IMPL_H */
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_STACK_H
|
||||
#define _SYS_STACK_H
|
||||
|
||||
#if defined(__i386) || defined(__amd64)
|
||||
|
||||
#include <sys/ia32/stack.h> /* XX64 x86/sys/stack.h */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_STACK_H */
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (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
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* 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 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TRAP_H
|
||||
#define _SYS_TRAP_H
|
||||
|
||||
#if defined(__i386) || defined(__amd64)
|
||||
|
||||
#include <sys/ia32/trap.h> /* XX64 x86/sys/trap.h */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_TRAP_H */
|
||||
Reference in New Issue
Block a user