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:
Tom Caputi
2016-05-12 10:51:24 -04:00
committed by Brian Behlendorf
parent be88e733a6
commit 0b04990a5d
90 changed files with 35834 additions and 80 deletions
+170
View File
@@ -0,0 +1,170 @@
/*
* 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 _AES_IMPL_H
#define _AES_IMPL_H
/*
* Common definitions used by AES.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/zfs_context.h>
#include <sys/crypto/common.h>
/* Similar to sysmacros.h IS_P2ALIGNED, but checks two pointers: */
#define IS_P2ALIGNED2(v, w, a) \
((((uintptr_t)(v) | (uintptr_t)(w)) & ((uintptr_t)(a) - 1)) == 0)
#define AES_BLOCK_LEN 16 /* bytes */
/* Round constant length, in number of 32-bit elements: */
#define RC_LENGTH (5 * ((AES_BLOCK_LEN) / 4 - 2))
#define AES_COPY_BLOCK(src, dst) \
(dst)[0] = (src)[0]; \
(dst)[1] = (src)[1]; \
(dst)[2] = (src)[2]; \
(dst)[3] = (src)[3]; \
(dst)[4] = (src)[4]; \
(dst)[5] = (src)[5]; \
(dst)[6] = (src)[6]; \
(dst)[7] = (src)[7]; \
(dst)[8] = (src)[8]; \
(dst)[9] = (src)[9]; \
(dst)[10] = (src)[10]; \
(dst)[11] = (src)[11]; \
(dst)[12] = (src)[12]; \
(dst)[13] = (src)[13]; \
(dst)[14] = (src)[14]; \
(dst)[15] = (src)[15]
#define AES_XOR_BLOCK(src, dst) \
(dst)[0] ^= (src)[0]; \
(dst)[1] ^= (src)[1]; \
(dst)[2] ^= (src)[2]; \
(dst)[3] ^= (src)[3]; \
(dst)[4] ^= (src)[4]; \
(dst)[5] ^= (src)[5]; \
(dst)[6] ^= (src)[6]; \
(dst)[7] ^= (src)[7]; \
(dst)[8] ^= (src)[8]; \
(dst)[9] ^= (src)[9]; \
(dst)[10] ^= (src)[10]; \
(dst)[11] ^= (src)[11]; \
(dst)[12] ^= (src)[12]; \
(dst)[13] ^= (src)[13]; \
(dst)[14] ^= (src)[14]; \
(dst)[15] ^= (src)[15]
/* AES key size definitions */
#define AES_MINBITS 128
#define AES_MINBYTES ((AES_MINBITS) >> 3)
#define AES_MAXBITS 256
#define AES_MAXBYTES ((AES_MAXBITS) >> 3)
#define AES_MIN_KEY_BYTES ((AES_MINBITS) >> 3)
#define AES_MAX_KEY_BYTES ((AES_MAXBITS) >> 3)
#define AES_192_KEY_BYTES 24
#define AES_IV_LEN 16
/* AES key schedule may be implemented with 32- or 64-bit elements: */
#define AES_32BIT_KS 32
#define AES_64BIT_KS 64
#define MAX_AES_NR 14 /* Maximum number of rounds */
#define MAX_AES_NB 4 /* Number of columns comprising a state */
typedef union {
#ifdef sun4u
uint64_t ks64[((MAX_AES_NR) + 1) * (MAX_AES_NB)];
#endif
uint32_t ks32[((MAX_AES_NR) + 1) * (MAX_AES_NB)];
} aes_ks_t;
/* aes_key.flags value: */
#define INTEL_AES_NI_CAPABLE 0x1 /* AES-NI instructions present */
typedef struct aes_key aes_key_t;
struct aes_key {
aes_ks_t encr_ks; /* encryption key schedule */
aes_ks_t decr_ks; /* decryption key schedule */
#ifdef __amd64
long double align128; /* Align fields above for Intel AES-NI */
int flags; /* implementation-dependent flags */
#endif /* __amd64 */
int nr; /* number of rounds (10, 12, or 14) */
int type; /* key schedule size (32 or 64 bits) */
};
/*
* Core AES functions.
* ks and keysched are pointers to aes_key_t.
* They are declared void* as they are intended to be opaque types.
* Use function aes_alloc_keysched() to allocate memory for ks and keysched.
*/
extern void *aes_alloc_keysched(size_t *size, int kmflag);
extern void aes_init_keysched(const uint8_t *cipherKey, uint_t keyBits,
void *keysched);
extern int aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct);
extern int aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt);
/*
* AES mode functions.
* The first 2 functions operate on 16-byte AES blocks.
*/
extern void aes_copy_block(uint8_t *in, uint8_t *out);
extern void aes_xor_block(uint8_t *data, uint8_t *dst);
/* Note: ctx is a pointer to aes_ctx_t defined in modes.h */
extern int aes_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
crypto_data_t *out);
extern int aes_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
crypto_data_t *out);
/*
* The following definitions and declarations are only used by AES FIPS POST
*/
#ifdef _AES_IMPL
typedef enum aes_mech_type {
AES_ECB_MECH_INFO_TYPE, /* SUN_CKM_AES_ECB */
AES_CBC_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC */
AES_CBC_PAD_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC_PAD */
AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */
AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */
AES_GCM_MECH_INFO_TYPE, /* SUN_CKM_AES_GCM */
AES_GMAC_MECH_INFO_TYPE /* SUN_CKM_AES_GMAC */
} aes_mech_type_t;
#endif /* _AES_IMPL */
#ifdef __cplusplus
}
#endif
#endif /* _AES_IMPL_H */
+385
View File
@@ -0,0 +1,385 @@
/*
* 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 _COMMON_CRYPTO_MODES_H
#define _COMMON_CRYPTO_MODES_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/zfs_context.h>
#include <sys/crypto/common.h>
#include <sys/crypto/impl.h>
#define ECB_MODE 0x00000002
#define CBC_MODE 0x00000004
#define CTR_MODE 0x00000008
#define CCM_MODE 0x00000010
#define GCM_MODE 0x00000020
#define GMAC_MODE 0x00000040
/*
* cc_keysched: Pointer to key schedule.
*
* cc_keysched_len: Length of the key schedule.
*
* cc_remainder: This is for residual data, i.e. data that can't
* be processed because there are too few bytes.
* Must wait until more data arrives.
*
* cc_remainder_len: Number of bytes in cc_remainder.
*
* cc_iv: Scratch buffer that sometimes contains the IV.
*
* cc_lastp: Pointer to previous block of ciphertext.
*
* cc_copy_to: Pointer to where encrypted residual data needs
* to be copied.
*
* cc_flags: PROVIDER_OWNS_KEY_SCHEDULE
* When a context is freed, it is necessary
* to know whether the key schedule was allocated
* by the caller, or internally, e.g. an init routine.
* If allocated by the latter, then it needs to be freed.
*
* ECB_MODE, CBC_MODE, CTR_MODE, or CCM_MODE
*/
struct common_ctx {
void *cc_keysched;
size_t cc_keysched_len;
uint64_t cc_iv[2];
uint64_t cc_remainder[2];
size_t cc_remainder_len;
uint8_t *cc_lastp;
uint8_t *cc_copy_to;
uint32_t cc_flags;
};
typedef struct common_ctx common_ctx_t;
typedef struct ecb_ctx {
struct common_ctx ecb_common;
uint64_t ecb_lastblock[2];
} ecb_ctx_t;
#define ecb_keysched ecb_common.cc_keysched
#define ecb_keysched_len ecb_common.cc_keysched_len
#define ecb_iv ecb_common.cc_iv
#define ecb_remainder ecb_common.cc_remainder
#define ecb_remainder_len ecb_common.cc_remainder_len
#define ecb_lastp ecb_common.cc_lastp
#define ecb_copy_to ecb_common.cc_copy_to
#define ecb_flags ecb_common.cc_flags
typedef struct cbc_ctx {
struct common_ctx cbc_common;
uint64_t cbc_lastblock[2];
} cbc_ctx_t;
#define cbc_keysched cbc_common.cc_keysched
#define cbc_keysched_len cbc_common.cc_keysched_len
#define cbc_iv cbc_common.cc_iv
#define cbc_remainder cbc_common.cc_remainder
#define cbc_remainder_len cbc_common.cc_remainder_len
#define cbc_lastp cbc_common.cc_lastp
#define cbc_copy_to cbc_common.cc_copy_to
#define cbc_flags cbc_common.cc_flags
/*
* ctr_lower_mask Bit-mask for lower 8 bytes of counter block.
* ctr_upper_mask Bit-mask for upper 8 bytes of counter block.
*/
typedef struct ctr_ctx {
struct common_ctx ctr_common;
uint64_t ctr_lower_mask;
uint64_t ctr_upper_mask;
uint32_t ctr_tmp[4];
} ctr_ctx_t;
/*
* ctr_cb Counter block.
*/
#define ctr_keysched ctr_common.cc_keysched
#define ctr_keysched_len ctr_common.cc_keysched_len
#define ctr_cb ctr_common.cc_iv
#define ctr_remainder ctr_common.cc_remainder
#define ctr_remainder_len ctr_common.cc_remainder_len
#define ctr_lastp ctr_common.cc_lastp
#define ctr_copy_to ctr_common.cc_copy_to
#define ctr_flags ctr_common.cc_flags
/*
*
* ccm_mac_len: Stores length of the MAC in CCM mode.
* ccm_mac_buf: Stores the intermediate value for MAC in CCM encrypt.
* In CCM decrypt, stores the input MAC value.
* ccm_data_len: Length of the plaintext for CCM mode encrypt, or
* length of the ciphertext for CCM mode decrypt.
* ccm_processed_data_len:
* Length of processed plaintext in CCM mode encrypt,
* or length of processed ciphertext for CCM mode decrypt.
* ccm_processed_mac_len:
* Length of MAC data accumulated in CCM mode decrypt.
*
* ccm_pt_buf: Only used in CCM mode decrypt. It stores the
* decrypted plaintext to be returned when
* MAC verification succeeds in decrypt_final.
* Memory for this should be allocated in the AES module.
*
*/
typedef struct ccm_ctx {
struct common_ctx ccm_common;
uint32_t ccm_tmp[4];
size_t ccm_mac_len;
uint64_t ccm_mac_buf[2];
size_t ccm_data_len;
size_t ccm_processed_data_len;
size_t ccm_processed_mac_len;
uint8_t *ccm_pt_buf;
uint64_t ccm_mac_input_buf[2];
uint64_t ccm_counter_mask;
} ccm_ctx_t;
#define ccm_keysched ccm_common.cc_keysched
#define ccm_keysched_len ccm_common.cc_keysched_len
#define ccm_cb ccm_common.cc_iv
#define ccm_remainder ccm_common.cc_remainder
#define ccm_remainder_len ccm_common.cc_remainder_len
#define ccm_lastp ccm_common.cc_lastp
#define ccm_copy_to ccm_common.cc_copy_to
#define ccm_flags ccm_common.cc_flags
/*
* gcm_tag_len: Length of authentication tag.
*
* gcm_ghash: Stores output from the GHASH function.
*
* gcm_processed_data_len:
* Length of processed plaintext (encrypt) or
* length of processed ciphertext (decrypt).
*
* gcm_pt_buf: Stores the decrypted plaintext returned by
* decrypt_final when the computed authentication
* tag matches the user supplied tag.
*
* gcm_pt_buf_len: Length of the plaintext buffer.
*
* gcm_H: Subkey.
*
* gcm_J0: Pre-counter block generated from the IV.
*
* gcm_len_a_len_c: 64-bit representations of the bit lengths of
* AAD and ciphertext.
*
* gcm_kmflag: Current value of kmflag. Used only for allocating
* the plaintext buffer during decryption.
*/
typedef struct gcm_ctx {
struct common_ctx gcm_common;
size_t gcm_tag_len;
size_t gcm_processed_data_len;
size_t gcm_pt_buf_len;
uint32_t gcm_tmp[4];
uint64_t gcm_ghash[2];
uint64_t gcm_H[2];
uint64_t gcm_J0[2];
uint64_t gcm_len_a_len_c[2];
uint8_t *gcm_pt_buf;
int gcm_kmflag;
} gcm_ctx_t;
#define gcm_keysched gcm_common.cc_keysched
#define gcm_keysched_len gcm_common.cc_keysched_len
#define gcm_cb gcm_common.cc_iv
#define gcm_remainder gcm_common.cc_remainder
#define gcm_remainder_len gcm_common.cc_remainder_len
#define gcm_lastp gcm_common.cc_lastp
#define gcm_copy_to gcm_common.cc_copy_to
#define gcm_flags gcm_common.cc_flags
#define AES_GMAC_IV_LEN 12
#define AES_GMAC_TAG_BITS 128
typedef struct aes_ctx {
union {
ecb_ctx_t acu_ecb;
cbc_ctx_t acu_cbc;
ctr_ctx_t acu_ctr;
ccm_ctx_t acu_ccm;
gcm_ctx_t acu_gcm;
} acu;
} aes_ctx_t;
#define ac_flags acu.acu_ecb.ecb_common.cc_flags
#define ac_remainder_len acu.acu_ecb.ecb_common.cc_remainder_len
#define ac_keysched acu.acu_ecb.ecb_common.cc_keysched
#define ac_keysched_len acu.acu_ecb.ecb_common.cc_keysched_len
#define ac_iv acu.acu_ecb.ecb_common.cc_iv
#define ac_lastp acu.acu_ecb.ecb_common.cc_lastp
#define ac_pt_buf acu.acu_ccm.ccm_pt_buf
#define ac_mac_len acu.acu_ccm.ccm_mac_len
#define ac_data_len acu.acu_ccm.ccm_data_len
#define ac_processed_mac_len acu.acu_ccm.ccm_processed_mac_len
#define ac_processed_data_len acu.acu_ccm.ccm_processed_data_len
#define ac_tag_len acu.acu_gcm.gcm_tag_len
typedef struct blowfish_ctx {
union {
ecb_ctx_t bcu_ecb;
cbc_ctx_t bcu_cbc;
} bcu;
} blowfish_ctx_t;
#define bc_flags bcu.bcu_ecb.ecb_common.cc_flags
#define bc_remainder_len bcu.bcu_ecb.ecb_common.cc_remainder_len
#define bc_keysched bcu.bcu_ecb.ecb_common.cc_keysched
#define bc_keysched_len bcu.bcu_ecb.ecb_common.cc_keysched_len
#define bc_iv bcu.bcu_ecb.ecb_common.cc_iv
#define bc_lastp bcu.bcu_ecb.ecb_common.cc_lastp
typedef struct des_ctx {
union {
ecb_ctx_t dcu_ecb;
cbc_ctx_t dcu_cbc;
} dcu;
} des_ctx_t;
#define dc_flags dcu.dcu_ecb.ecb_common.cc_flags
#define dc_remainder_len dcu.dcu_ecb.ecb_common.cc_remainder_len
#define dc_keysched dcu.dcu_ecb.ecb_common.cc_keysched
#define dc_keysched_len dcu.dcu_ecb.ecb_common.cc_keysched_len
#define dc_iv dcu.dcu_ecb.ecb_common.cc_iv
#define dc_lastp dcu.dcu_ecb.ecb_common.cc_lastp
extern int ecb_cipher_contiguous_blocks(ecb_ctx_t *, char *, size_t,
crypto_data_t *, size_t, int (*cipher)(const void *, const uint8_t *,
uint8_t *));
extern int cbc_encrypt_contiguous_blocks(cbc_ctx_t *, char *, size_t,
crypto_data_t *, size_t,
int (*encrypt)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int cbc_decrypt_contiguous_blocks(cbc_ctx_t *, char *, size_t,
crypto_data_t *, size_t,
int (*decrypt)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int ctr_mode_contiguous_blocks(ctr_ctx_t *, char *, size_t,
crypto_data_t *, size_t,
int (*cipher)(const void *, const uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t,
crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t,
crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int gcm_mode_encrypt_contiguous_blocks(gcm_ctx_t *, char *, size_t,
crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int gcm_mode_decrypt_contiguous_blocks(gcm_ctx_t *, char *, size_t,
crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
int ccm_encrypt_final(ccm_ctx_t *, crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
int gcm_encrypt_final(gcm_ctx_t *, crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int ccm_decrypt_final(ccm_ctx_t *, crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int gcm_decrypt_final(gcm_ctx_t *, crypto_data_t *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int ctr_mode_final(ctr_ctx_t *, crypto_data_t *,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *));
extern int cbc_init_ctx(cbc_ctx_t *, char *, size_t, size_t,
void (*copy_block)(uint8_t *, uint64_t *));
extern int ctr_init_ctx(ctr_ctx_t *, ulong_t, uint8_t *,
void (*copy_block)(uint8_t *, uint8_t *));
extern int ccm_init_ctx(ccm_ctx_t *, char *, int, boolean_t, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int gcm_init_ctx(gcm_ctx_t *, char *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern int gmac_init_ctx(gcm_ctx_t *, char *, size_t,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
void (*copy_block)(uint8_t *, uint8_t *),
void (*xor_block)(uint8_t *, uint8_t *));
extern void calculate_ccm_mac(ccm_ctx_t *, uint8_t *,
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *));
extern void gcm_mul(uint64_t *, uint64_t *, uint64_t *);
extern void crypto_init_ptrs(crypto_data_t *, void **, offset_t *);
extern void crypto_get_ptrs(crypto_data_t *, void **, offset_t *,
uint8_t **, size_t *, uint8_t **, size_t);
extern void *ecb_alloc_ctx(int);
extern void *cbc_alloc_ctx(int);
extern void *ctr_alloc_ctx(int);
extern void *ccm_alloc_ctx(int);
extern void *gcm_alloc_ctx(int);
extern void *gmac_alloc_ctx(int);
extern void crypto_free_mode_ctx(void *);
extern void gcm_set_kmflag(gcm_ctx_t *, int);
#ifdef __cplusplus
}
#endif
#endif /* _COMMON_CRYPTO_MODES_H */
+61
View File
@@ -0,0 +1,61 @@
/*
* 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_SHA1_H
#define _SYS_SHA1_H
#include <sys/types.h> /* for uint_* */
#ifdef __cplusplus
extern "C" {
#endif
/*
* NOTE: n2rng (Niagara2 RNG driver) accesses the state field of
* SHA1_CTX directly. NEVER change this structure without verifying
* compatiblity with n2rng. The important thing is that the state
* must be in a field declared as uint32_t state[5].
*/
/* SHA-1 context. */
typedef struct {
uint32_t state[5]; /* state (ABCDE) */
uint32_t count[2]; /* number of bits, modulo 2^64 (msb first) */
union {
uint8_t buf8[64]; /* undigested input */
uint32_t buf32[16]; /* realigned input */
} buf_un;
} SHA1_CTX;
#define SHA1_DIGEST_LENGTH 20
void SHA1Init(SHA1_CTX *);
void SHA1Update(SHA1_CTX *, const void *, size_t);
void SHA1Final(void *, SHA1_CTX *);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SHA1_H */
+65
View File
@@ -0,0 +1,65 @@
/*
* 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 (c) 1998, by Sun Microsystems, Inc.
* All rights reserved.
*/
#ifndef _SYS_SHA1_CONSTS_H
#define _SYS_SHA1_CONSTS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* as explained in sha1.c, loading 32-bit constants on a sparc is expensive
* since it involves both a `sethi' and an `or'. thus, we instead use `ld'
* to load the constants from an array called `sha1_consts'. however, on
* intel (and perhaps other processors), it is cheaper to load the constant
* directly. thus, the c code in SHA1Transform() uses the macro SHA1_CONST()
* which either expands to a constant or an array reference, depending on
* the architecture the code is being compiled for.
*/
#include <sys/types.h> /* uint32_t */
extern const uint32_t sha1_consts[];
#if defined(__sparc)
#define SHA1_CONST(x) (sha1_consts[x])
#else
#define SHA1_CONST(x) (SHA1_CONST_ ## x)
#endif
/* constants, as provided in FIPS 180-1 */
#define SHA1_CONST_0 0x5a827999U
#define SHA1_CONST_1 0x6ed9eba1U
#define SHA1_CONST_2 0x8f1bbcdcU
#define SHA1_CONST_3 0xca62c1d6U
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SHA1_CONSTS_H */
+73
View File
@@ -0,0 +1,73 @@
/*
* 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 _SHA1_IMPL_H
#define _SHA1_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
#define SHA1_HASH_SIZE 20 /* SHA_1 digest length in bytes */
#define SHA1_DIGEST_LENGTH 20 /* SHA1 digest length in bytes */
#define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */
#define SHA1_HMAC_MIN_KEY_LEN 1 /* SHA1-HMAC min key length in bytes */
#define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bytes */
#define SHA1_HMAC_INTS_PER_BLOCK (SHA1_HMAC_BLOCK_SIZE/sizeof (uint32_t))
/*
* CSPI information (entry points, provider info, etc.)
*/
typedef enum sha1_mech_type {
SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */
SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */
SHA1_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_SHA1_HMAC_GENERAL */
} sha1_mech_type_t;
/*
* Context for SHA1 mechanism.
*/
typedef struct sha1_ctx {
sha1_mech_type_t sc_mech_type; /* type of context */
SHA1_CTX sc_sha1_ctx; /* SHA1 context */
} sha1_ctx_t;
/*
* Context for SHA1-HMAC and SHA1-HMAC-GENERAL mechanisms.
*/
typedef struct sha1_hmac_ctx {
sha1_mech_type_t hc_mech_type; /* type of context */
uint32_t hc_digest_len; /* digest len in bytes */
SHA1_CTX hc_icontext; /* inner SHA1 context */
SHA1_CTX hc_ocontext; /* outer SHA1 context */
} sha1_hmac_ctx_t;
#ifdef __cplusplus
}
#endif
#endif /* _SHA1_IMPL_H */
+116
View File
@@ -0,0 +1,116 @@
/*
* 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.
*/
/* Copyright 2013 Saso Kiselkov. All rights reserved. */
#ifndef _SYS_SHA2_H
#define _SYS_SHA2_H
#include <sys/types.h> /* for uint_* */
#ifdef __cplusplus
extern "C" {
#endif
#define SHA2_HMAC_MIN_KEY_LEN 1 /* SHA2-HMAC min key length in bytes */
#define SHA2_HMAC_MAX_KEY_LEN INT_MAX /* SHA2-HMAC max key length in bytes */
#define SHA256_DIGEST_LENGTH 32 /* SHA256 digest length in bytes */
#define SHA256_HMAC_BLOCK_SIZE 64 /* SHA256-HMAC block size */
#define SHA256 0
#define SHA256_HMAC 1
#define SHA256_HMAC_GEN 2
/*
* SHA2 context.
* The contents of this structure are a private interface between the
* Init/Update/Final calls of the functions defined below.
* Callers must never attempt to read or write any of the fields
* in this structure directly.
*/
typedef struct {
uint32_t algotype; /* Algorithm Type */
/* state (ABCDEFGH) */
union {
uint32_t s32[8]; /* for SHA256 */
uint64_t s64[8]; /* for SHA384/512 */
} state;
/* number of bits */
union {
uint32_t c32[2]; /* for SHA256 , modulo 2^64 */
uint64_t c64[2]; /* for SHA384/512, modulo 2^128 */
} count;
union {
uint8_t buf8[128]; /* undigested input */
uint32_t buf32[32]; /* realigned input */
uint64_t buf64[16]; /* realigned input */
} buf_un;
} SHA2_CTX;
typedef SHA2_CTX SHA256_CTX;
typedef SHA2_CTX SHA384_CTX;
typedef SHA2_CTX SHA512_CTX;
extern void SHA2Init(uint64_t mech, SHA2_CTX *);
extern void SHA2Update(SHA2_CTX *, const void *, size_t);
extern void SHA2Final(void *, SHA2_CTX *);
extern void SHA256Init(SHA256_CTX *);
extern void SHA256Update(SHA256_CTX *, const void *, size_t);
extern void SHA256Final(void *, SHA256_CTX *);
#ifdef _SHA2_IMPL
/*
* The following types/functions are all private to the implementation
* of the SHA2 functions and must not be used by consumers of the interface
*/
/*
* List of support mechanisms in this module.
*
* It is important to note that in the module, division or modulus calculations
* are used on the enumerated type to determine which mechanism is being used;
* therefore, changing the order or additional mechanisms should be done
* carefully
*/
typedef enum sha2_mech_type {
SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
} sha2_mech_type_t;
#endif /* _SHA2_IMPL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SHA2_H */
+219
View File
@@ -0,0 +1,219 @@
/*
* 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_SHA2_CONSTS_H
#define _SYS_SHA2_CONSTS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Loading 32-bit constants on a sparc is expensive since it involves both
* a `sethi' and an `or'. thus, we instead use `ld' to load the constants
* from an array called `sha2_consts'. however, on intel (and perhaps other
* processors), it is cheaper to load the constant directly. thus, the c
* code in SHA transform functions uses the macro SHA2_CONST() which either
* expands to a constant or an array reference, depending on
* the architecture the code is being compiled for.
*
* SHA512 constants are used for SHA384
*/
#include <sys/types.h> /* uint32_t */
extern const uint32_t sha256_consts[];
extern const uint64_t sha512_consts[];
#if defined(__sparc)
#define SHA256_CONST(x) (sha256_consts[x])
#define SHA512_CONST(x) (sha512_consts[x])
#else
#define SHA256_CONST(x) (SHA256_CONST_ ## x)
#define SHA512_CONST(x) (SHA512_CONST_ ## x)
#endif
/* constants, as provided in FIPS 180-2 */
#define SHA256_CONST_0 0x428a2f98U
#define SHA256_CONST_1 0x71374491U
#define SHA256_CONST_2 0xb5c0fbcfU
#define SHA256_CONST_3 0xe9b5dba5U
#define SHA256_CONST_4 0x3956c25bU
#define SHA256_CONST_5 0x59f111f1U
#define SHA256_CONST_6 0x923f82a4U
#define SHA256_CONST_7 0xab1c5ed5U
#define SHA256_CONST_8 0xd807aa98U
#define SHA256_CONST_9 0x12835b01U
#define SHA256_CONST_10 0x243185beU
#define SHA256_CONST_11 0x550c7dc3U
#define SHA256_CONST_12 0x72be5d74U
#define SHA256_CONST_13 0x80deb1feU
#define SHA256_CONST_14 0x9bdc06a7U
#define SHA256_CONST_15 0xc19bf174U
#define SHA256_CONST_16 0xe49b69c1U
#define SHA256_CONST_17 0xefbe4786U
#define SHA256_CONST_18 0x0fc19dc6U
#define SHA256_CONST_19 0x240ca1ccU
#define SHA256_CONST_20 0x2de92c6fU
#define SHA256_CONST_21 0x4a7484aaU
#define SHA256_CONST_22 0x5cb0a9dcU
#define SHA256_CONST_23 0x76f988daU
#define SHA256_CONST_24 0x983e5152U
#define SHA256_CONST_25 0xa831c66dU
#define SHA256_CONST_26 0xb00327c8U
#define SHA256_CONST_27 0xbf597fc7U
#define SHA256_CONST_28 0xc6e00bf3U
#define SHA256_CONST_29 0xd5a79147U
#define SHA256_CONST_30 0x06ca6351U
#define SHA256_CONST_31 0x14292967U
#define SHA256_CONST_32 0x27b70a85U
#define SHA256_CONST_33 0x2e1b2138U
#define SHA256_CONST_34 0x4d2c6dfcU
#define SHA256_CONST_35 0x53380d13U
#define SHA256_CONST_36 0x650a7354U
#define SHA256_CONST_37 0x766a0abbU
#define SHA256_CONST_38 0x81c2c92eU
#define SHA256_CONST_39 0x92722c85U
#define SHA256_CONST_40 0xa2bfe8a1U
#define SHA256_CONST_41 0xa81a664bU
#define SHA256_CONST_42 0xc24b8b70U
#define SHA256_CONST_43 0xc76c51a3U
#define SHA256_CONST_44 0xd192e819U
#define SHA256_CONST_45 0xd6990624U
#define SHA256_CONST_46 0xf40e3585U
#define SHA256_CONST_47 0x106aa070U
#define SHA256_CONST_48 0x19a4c116U
#define SHA256_CONST_49 0x1e376c08U
#define SHA256_CONST_50 0x2748774cU
#define SHA256_CONST_51 0x34b0bcb5U
#define SHA256_CONST_52 0x391c0cb3U
#define SHA256_CONST_53 0x4ed8aa4aU
#define SHA256_CONST_54 0x5b9cca4fU
#define SHA256_CONST_55 0x682e6ff3U
#define SHA256_CONST_56 0x748f82eeU
#define SHA256_CONST_57 0x78a5636fU
#define SHA256_CONST_58 0x84c87814U
#define SHA256_CONST_59 0x8cc70208U
#define SHA256_CONST_60 0x90befffaU
#define SHA256_CONST_61 0xa4506cebU
#define SHA256_CONST_62 0xbef9a3f7U
#define SHA256_CONST_63 0xc67178f2U
#define SHA512_CONST_0 0x428a2f98d728ae22ULL
#define SHA512_CONST_1 0x7137449123ef65cdULL
#define SHA512_CONST_2 0xb5c0fbcfec4d3b2fULL
#define SHA512_CONST_3 0xe9b5dba58189dbbcULL
#define SHA512_CONST_4 0x3956c25bf348b538ULL
#define SHA512_CONST_5 0x59f111f1b605d019ULL
#define SHA512_CONST_6 0x923f82a4af194f9bULL
#define SHA512_CONST_7 0xab1c5ed5da6d8118ULL
#define SHA512_CONST_8 0xd807aa98a3030242ULL
#define SHA512_CONST_9 0x12835b0145706fbeULL
#define SHA512_CONST_10 0x243185be4ee4b28cULL
#define SHA512_CONST_11 0x550c7dc3d5ffb4e2ULL
#define SHA512_CONST_12 0x72be5d74f27b896fULL
#define SHA512_CONST_13 0x80deb1fe3b1696b1ULL
#define SHA512_CONST_14 0x9bdc06a725c71235ULL
#define SHA512_CONST_15 0xc19bf174cf692694ULL
#define SHA512_CONST_16 0xe49b69c19ef14ad2ULL
#define SHA512_CONST_17 0xefbe4786384f25e3ULL
#define SHA512_CONST_18 0x0fc19dc68b8cd5b5ULL
#define SHA512_CONST_19 0x240ca1cc77ac9c65ULL
#define SHA512_CONST_20 0x2de92c6f592b0275ULL
#define SHA512_CONST_21 0x4a7484aa6ea6e483ULL
#define SHA512_CONST_22 0x5cb0a9dcbd41fbd4ULL
#define SHA512_CONST_23 0x76f988da831153b5ULL
#define SHA512_CONST_24 0x983e5152ee66dfabULL
#define SHA512_CONST_25 0xa831c66d2db43210ULL
#define SHA512_CONST_26 0xb00327c898fb213fULL
#define SHA512_CONST_27 0xbf597fc7beef0ee4ULL
#define SHA512_CONST_28 0xc6e00bf33da88fc2ULL
#define SHA512_CONST_29 0xd5a79147930aa725ULL
#define SHA512_CONST_30 0x06ca6351e003826fULL
#define SHA512_CONST_31 0x142929670a0e6e70ULL
#define SHA512_CONST_32 0x27b70a8546d22ffcULL
#define SHA512_CONST_33 0x2e1b21385c26c926ULL
#define SHA512_CONST_34 0x4d2c6dfc5ac42aedULL
#define SHA512_CONST_35 0x53380d139d95b3dfULL
#define SHA512_CONST_36 0x650a73548baf63deULL
#define SHA512_CONST_37 0x766a0abb3c77b2a8ULL
#define SHA512_CONST_38 0x81c2c92e47edaee6ULL
#define SHA512_CONST_39 0x92722c851482353bULL
#define SHA512_CONST_40 0xa2bfe8a14cf10364ULL
#define SHA512_CONST_41 0xa81a664bbc423001ULL
#define SHA512_CONST_42 0xc24b8b70d0f89791ULL
#define SHA512_CONST_43 0xc76c51a30654be30ULL
#define SHA512_CONST_44 0xd192e819d6ef5218ULL
#define SHA512_CONST_45 0xd69906245565a910ULL
#define SHA512_CONST_46 0xf40e35855771202aULL
#define SHA512_CONST_47 0x106aa07032bbd1b8ULL
#define SHA512_CONST_48 0x19a4c116b8d2d0c8ULL
#define SHA512_CONST_49 0x1e376c085141ab53ULL
#define SHA512_CONST_50 0x2748774cdf8eeb99ULL
#define SHA512_CONST_51 0x34b0bcb5e19b48a8ULL
#define SHA512_CONST_52 0x391c0cb3c5c95a63ULL
#define SHA512_CONST_53 0x4ed8aa4ae3418acbULL
#define SHA512_CONST_54 0x5b9cca4f7763e373ULL
#define SHA512_CONST_55 0x682e6ff3d6b2b8a3ULL
#define SHA512_CONST_56 0x748f82ee5defb2fcULL
#define SHA512_CONST_57 0x78a5636f43172f60ULL
#define SHA512_CONST_58 0x84c87814a1f0ab72ULL
#define SHA512_CONST_59 0x8cc702081a6439ecULL
#define SHA512_CONST_60 0x90befffa23631e28ULL
#define SHA512_CONST_61 0xa4506cebde82bde9ULL
#define SHA512_CONST_62 0xbef9a3f7b2c67915ULL
#define SHA512_CONST_63 0xc67178f2e372532bULL
#define SHA512_CONST_64 0xca273eceea26619cULL
#define SHA512_CONST_65 0xd186b8c721c0c207ULL
#define SHA512_CONST_66 0xeada7dd6cde0eb1eULL
#define SHA512_CONST_67 0xf57d4f7fee6ed178ULL
#define SHA512_CONST_68 0x06f067aa72176fbaULL
#define SHA512_CONST_69 0x0a637dc5a2c898a6ULL
#define SHA512_CONST_70 0x113f9804bef90daeULL
#define SHA512_CONST_71 0x1b710b35131c471bULL
#define SHA512_CONST_72 0x28db77f523047d84ULL
#define SHA512_CONST_73 0x32caab7b40c72493ULL
#define SHA512_CONST_74 0x3c9ebe0a15c9bebcULL
#define SHA512_CONST_75 0x431d67c49c100d4cULL
#define SHA512_CONST_76 0x4cc5d4becb3e42b6ULL
#define SHA512_CONST_77 0x597f299cfc657e2aULL
#define SHA512_CONST_78 0x5fcb6fab3ad6faecULL
#define SHA512_CONST_79 0x6c44198c4a475817ULL
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SHA2_CONSTS_H */
+62
View File
@@ -0,0 +1,62 @@
/*
* 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 _SHA2_IMPL_H
#define _SHA2_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
SHA1_TYPE,
SHA256_TYPE,
SHA384_TYPE,
SHA512_TYPE
} sha2_mech_t;
/*
* Context for SHA2 mechanism.
*/
typedef struct sha2_ctx {
sha2_mech_type_t sc_mech_type; /* type of context */
SHA2_CTX sc_sha2_ctx; /* SHA2 context */
} sha2_ctx_t;
/*
* Context for SHA2 HMAC and HMAC GENERAL mechanisms.
*/
typedef struct sha2_hmac_ctx {
sha2_mech_type_t hc_mech_type; /* type of context */
uint32_t hc_digest_len; /* digest len in bytes */
SHA2_CTX hc_icontext; /* inner SHA2 context */
SHA2_CTX hc_ocontext; /* outer SHA2 context */
} sha2_hmac_ctx_t;
#ifdef __cplusplus
}
#endif
#endif /* _SHA2_IMPL_H */
+36
View File
@@ -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 */
+183
View File
@@ -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 */
+137
View File
@@ -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
+136
View File
@@ -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 */
+630
View File
@@ -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 */
+531
View File
@@ -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 */
+721
View File
@@ -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 */
+307
View File
@@ -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 */
+160
View File
@@ -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 */
+107
View File
@@ -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 */
+477
View File
@@ -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 */
+147
View File
@@ -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 */
+108
View File
@@ -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 */
+36
View File
@@ -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 */
+36
View File
@@ -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 */