mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
Illumos Crypto Port module added to enable native encryption in zfs
A port of the Illumos Crypto Framework to a Linux kernel module (found in module/icp). This is needed to do the actual encryption work. We cannot use the Linux kernel's built in crypto api because it is only exported to GPL-licensed modules. Having the ICP also means the crypto code can run on any of the other kernels under OpenZFS. I ended up porting over most of the internals of the framework, which means that porting over other API calls (if we need them) should be fairly easy. Specifically, I have ported over the API functions related to encryption, digests, macs, and crypto templates. The ICP is able to use assembly-accelerated encryption on amd64 machines and AES-NI instructions on Intel chips that support it. There are place-holder directories for similar assembly optimizations for other architectures (although they have not been written). Signed-off-by: Tom Caputi <tcaputi@datto.com> Signed-off-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Issue #4329
This commit is contained in:
committed by
Brian Behlendorf
parent
be88e733a6
commit
0b04990a5d
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_ELFSIGN_H
|
||||
#define _SYS_CRYPTO_ELFSIGN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Consolidation Private Interface for elfsign/libpkcs11/kcfd
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
/*
|
||||
* Project Private structures and types used for communication between kcfd
|
||||
* and KCF over the door.
|
||||
*/
|
||||
|
||||
typedef enum ELFsign_status_e {
|
||||
ELFSIGN_UNKNOWN,
|
||||
ELFSIGN_SUCCESS,
|
||||
ELFSIGN_FAILED,
|
||||
ELFSIGN_NOTSIGNED,
|
||||
ELFSIGN_INVALID_CERTPATH,
|
||||
ELFSIGN_INVALID_ELFOBJ,
|
||||
ELFSIGN_RESTRICTED
|
||||
} ELFsign_status_t;
|
||||
|
||||
#define KCF_KCFD_VERSION1 1
|
||||
#define SIG_MAX_LENGTH 1024
|
||||
|
||||
#define ELF_SIGNATURE_SECTION ".SUNW_signature"
|
||||
|
||||
typedef struct kcf_door_arg_s {
|
||||
short da_version;
|
||||
boolean_t da_iskernel;
|
||||
|
||||
union {
|
||||
char filename[MAXPATHLEN]; /* For request */
|
||||
|
||||
struct kcf_door_result_s { /* For response */
|
||||
ELFsign_status_t status;
|
||||
uint32_t siglen;
|
||||
uchar_t signature[1];
|
||||
} result;
|
||||
} da_u;
|
||||
} kcf_door_arg_t;
|
||||
|
||||
typedef uint32_t filesig_vers_t;
|
||||
|
||||
/*
|
||||
* File Signature Structure
|
||||
* Applicable to ELF and other file formats
|
||||
*/
|
||||
struct filesignatures {
|
||||
uint32_t filesig_cnt; /* count of signatures */
|
||||
uint32_t filesig_pad; /* unused */
|
||||
union {
|
||||
char filesig_data[1];
|
||||
struct filesig { /* one of these for each signature */
|
||||
uint32_t filesig_size;
|
||||
filesig_vers_t filesig_version;
|
||||
union {
|
||||
struct filesig_version1 {
|
||||
uint32_t filesig_v1_dnsize;
|
||||
uint32_t filesig_v1_sigsize;
|
||||
uint32_t filesig_v1_oidsize;
|
||||
char filesig_v1_data[1];
|
||||
} filesig_v1;
|
||||
struct filesig_version3 {
|
||||
uint64_t filesig_v3_time;
|
||||
uint32_t filesig_v3_dnsize;
|
||||
uint32_t filesig_v3_sigsize;
|
||||
uint32_t filesig_v3_oidsize;
|
||||
char filesig_v3_data[1];
|
||||
} filesig_v3;
|
||||
} _u2;
|
||||
} filesig_sig;
|
||||
uint64_t filesig_align;
|
||||
} _u1;
|
||||
};
|
||||
#define filesig_sig _u1.filesig_sig
|
||||
|
||||
#define filesig_v1_dnsize _u2.filesig_v1.filesig_v1_dnsize
|
||||
#define filesig_v1_sigsize _u2.filesig_v1.filesig_v1_sigsize
|
||||
#define filesig_v1_oidsize _u2.filesig_v1.filesig_v1_oidsize
|
||||
#define filesig_v1_data _u2.filesig_v1.filesig_v1_data
|
||||
|
||||
#define filesig_v3_time _u2.filesig_v3.filesig_v3_time
|
||||
#define filesig_v3_dnsize _u2.filesig_v3.filesig_v3_dnsize
|
||||
#define filesig_v3_sigsize _u2.filesig_v3.filesig_v3_sigsize
|
||||
#define filesig_v3_oidsize _u2.filesig_v3.filesig_v3_oidsize
|
||||
#define filesig_v3_data _u2.filesig_v3.filesig_v3_data
|
||||
|
||||
#define filesig_ALIGN(s) (((s) + sizeof (uint64_t) - 1) & \
|
||||
(-sizeof (uint64_t)))
|
||||
#define filesig_next(ptr) (struct filesig *)((void *)((char *)(ptr) + \
|
||||
filesig_ALIGN((ptr)->filesig_size)))
|
||||
|
||||
#define FILESIG_UNKNOWN 0 /* unrecognized version */
|
||||
#define FILESIG_VERSION1 1 /* version1, all but sig section */
|
||||
#define FILESIG_VERSION2 2 /* version1 format, SHF_ALLOC only */
|
||||
#define FILESIG_VERSION3 3 /* version3, all but sig section */
|
||||
#define FILESIG_VERSION4 4 /* version3 format, SHF_ALLOC only */
|
||||
|
||||
#define _PATH_KCFD_DOOR "/etc/svc/volatile/kcfd_door"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_ELFSIGN_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_IOCTLADMIN_H
|
||||
#define _SYS_CRYPTO_IOCTLADMIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/common.h>
|
||||
|
||||
#define ADMIN_IOCTL_DEVICE "/dev/cryptoadm"
|
||||
|
||||
#define CRYPTOADMIN(x) (('y' << 8) | (x))
|
||||
|
||||
/*
|
||||
* Administrative IOCTLs
|
||||
*/
|
||||
|
||||
typedef struct crypto_get_dev_list {
|
||||
uint_t dl_return_value;
|
||||
uint_t dl_dev_count;
|
||||
crypto_dev_list_entry_t dl_devs[1];
|
||||
} crypto_get_dev_list_t;
|
||||
|
||||
typedef struct crypto_get_soft_list {
|
||||
uint_t sl_return_value;
|
||||
uint_t sl_soft_count;
|
||||
size_t sl_soft_len;
|
||||
caddr_t sl_soft_names;
|
||||
} crypto_get_soft_list_t;
|
||||
|
||||
typedef struct crypto_get_dev_info {
|
||||
uint_t di_return_value;
|
||||
char di_dev_name[MAXNAMELEN];
|
||||
uint_t di_dev_instance;
|
||||
uint_t di_count;
|
||||
crypto_mech_name_t di_list[1];
|
||||
} crypto_get_dev_info_t;
|
||||
|
||||
typedef struct crypto_get_soft_info {
|
||||
uint_t si_return_value;
|
||||
char si_name[MAXNAMELEN];
|
||||
uint_t si_count;
|
||||
crypto_mech_name_t si_list[1];
|
||||
} crypto_get_soft_info_t;
|
||||
|
||||
typedef struct crypto_load_dev_disabled {
|
||||
uint_t dd_return_value;
|
||||
char dd_dev_name[MAXNAMELEN];
|
||||
uint_t dd_dev_instance;
|
||||
uint_t dd_count;
|
||||
crypto_mech_name_t dd_list[1];
|
||||
} crypto_load_dev_disabled_t;
|
||||
|
||||
typedef struct crypto_load_soft_disabled {
|
||||
uint_t sd_return_value;
|
||||
char sd_name[MAXNAMELEN];
|
||||
uint_t sd_count;
|
||||
crypto_mech_name_t sd_list[1];
|
||||
} crypto_load_soft_disabled_t;
|
||||
|
||||
typedef struct crypto_unload_soft_module {
|
||||
uint_t sm_return_value;
|
||||
char sm_name[MAXNAMELEN];
|
||||
} crypto_unload_soft_module_t;
|
||||
|
||||
typedef struct crypto_load_soft_config {
|
||||
uint_t sc_return_value;
|
||||
char sc_name[MAXNAMELEN];
|
||||
uint_t sc_count;
|
||||
crypto_mech_name_t sc_list[1];
|
||||
} crypto_load_soft_config_t;
|
||||
|
||||
typedef struct crypto_load_door {
|
||||
uint_t ld_return_value;
|
||||
uint_t ld_did;
|
||||
} crypto_load_door_t;
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef _SYSCALL32
|
||||
|
||||
typedef struct crypto_get_soft_list32 {
|
||||
uint32_t sl_return_value;
|
||||
uint32_t sl_soft_count;
|
||||
size32_t sl_soft_len;
|
||||
caddr32_t sl_soft_names;
|
||||
} crypto_get_soft_list32_t;
|
||||
|
||||
#endif /* _SYSCALL32 */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define CRYPTO_GET_VERSION CRYPTOADMIN(1)
|
||||
#define CRYPTO_GET_DEV_LIST CRYPTOADMIN(2)
|
||||
#define CRYPTO_GET_SOFT_LIST CRYPTOADMIN(3)
|
||||
#define CRYPTO_GET_DEV_INFO CRYPTOADMIN(4)
|
||||
#define CRYPTO_GET_SOFT_INFO CRYPTOADMIN(5)
|
||||
#define CRYPTO_LOAD_DEV_DISABLED CRYPTOADMIN(8)
|
||||
#define CRYPTO_LOAD_SOFT_DISABLED CRYPTOADMIN(9)
|
||||
#define CRYPTO_UNLOAD_SOFT_MODULE CRYPTOADMIN(10)
|
||||
#define CRYPTO_LOAD_SOFT_CONFIG CRYPTOADMIN(11)
|
||||
#define CRYPTO_POOL_CREATE CRYPTOADMIN(12)
|
||||
#define CRYPTO_POOL_WAIT CRYPTOADMIN(13)
|
||||
#define CRYPTO_POOL_RUN CRYPTOADMIN(14)
|
||||
#define CRYPTO_LOAD_DOOR CRYPTOADMIN(15)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_IOCTLADMIN_H */
|
||||
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_OPS_IMPL_H
|
||||
#define _SYS_CRYPTO_OPS_IMPL_H
|
||||
|
||||
/*
|
||||
* Scheduler internal structures.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/api.h>
|
||||
#include <sys/crypto/spi.h>
|
||||
#include <sys/crypto/impl.h>
|
||||
#include <sys/crypto/common.h>
|
||||
|
||||
/*
|
||||
* The parameters needed for each function group are batched
|
||||
* in one structure. This is much simpler than having a
|
||||
* separate structure for each function.
|
||||
*
|
||||
* In some cases, a field is generically named to keep the
|
||||
* structure small. The comments indicate these cases.
|
||||
*/
|
||||
typedef struct kcf_digest_ops_params {
|
||||
crypto_session_id_t do_sid;
|
||||
crypto_mech_type_t do_framework_mechtype;
|
||||
crypto_mechanism_t do_mech;
|
||||
crypto_data_t *do_data;
|
||||
crypto_data_t *do_digest;
|
||||
crypto_key_t *do_digest_key; /* Argument for digest_key() */
|
||||
} kcf_digest_ops_params_t;
|
||||
|
||||
typedef struct kcf_mac_ops_params {
|
||||
crypto_session_id_t mo_sid;
|
||||
crypto_mech_type_t mo_framework_mechtype;
|
||||
crypto_mechanism_t mo_mech;
|
||||
crypto_key_t *mo_key;
|
||||
crypto_data_t *mo_data;
|
||||
crypto_data_t *mo_mac;
|
||||
crypto_spi_ctx_template_t mo_templ;
|
||||
} kcf_mac_ops_params_t;
|
||||
|
||||
typedef struct kcf_encrypt_ops_params {
|
||||
crypto_session_id_t eo_sid;
|
||||
crypto_mech_type_t eo_framework_mechtype;
|
||||
crypto_mechanism_t eo_mech;
|
||||
crypto_key_t *eo_key;
|
||||
crypto_data_t *eo_plaintext;
|
||||
crypto_data_t *eo_ciphertext;
|
||||
crypto_spi_ctx_template_t eo_templ;
|
||||
} kcf_encrypt_ops_params_t;
|
||||
|
||||
typedef struct kcf_decrypt_ops_params {
|
||||
crypto_session_id_t dop_sid;
|
||||
crypto_mech_type_t dop_framework_mechtype;
|
||||
crypto_mechanism_t dop_mech;
|
||||
crypto_key_t *dop_key;
|
||||
crypto_data_t *dop_ciphertext;
|
||||
crypto_data_t *dop_plaintext;
|
||||
crypto_spi_ctx_template_t dop_templ;
|
||||
} kcf_decrypt_ops_params_t;
|
||||
|
||||
typedef struct kcf_sign_ops_params {
|
||||
crypto_session_id_t so_sid;
|
||||
crypto_mech_type_t so_framework_mechtype;
|
||||
crypto_mechanism_t so_mech;
|
||||
crypto_key_t *so_key;
|
||||
crypto_data_t *so_data;
|
||||
crypto_data_t *so_signature;
|
||||
crypto_spi_ctx_template_t so_templ;
|
||||
} kcf_sign_ops_params_t;
|
||||
|
||||
typedef struct kcf_verify_ops_params {
|
||||
crypto_session_id_t vo_sid;
|
||||
crypto_mech_type_t vo_framework_mechtype;
|
||||
crypto_mechanism_t vo_mech;
|
||||
crypto_key_t *vo_key;
|
||||
crypto_data_t *vo_data;
|
||||
crypto_data_t *vo_signature;
|
||||
crypto_spi_ctx_template_t vo_templ;
|
||||
} kcf_verify_ops_params_t;
|
||||
|
||||
typedef struct kcf_encrypt_mac_ops_params {
|
||||
crypto_session_id_t em_sid;
|
||||
crypto_mech_type_t em_framework_encr_mechtype;
|
||||
crypto_mechanism_t em_encr_mech;
|
||||
crypto_key_t *em_encr_key;
|
||||
crypto_mech_type_t em_framework_mac_mechtype;
|
||||
crypto_mechanism_t em_mac_mech;
|
||||
crypto_key_t *em_mac_key;
|
||||
crypto_data_t *em_plaintext;
|
||||
crypto_dual_data_t *em_ciphertext;
|
||||
crypto_data_t *em_mac;
|
||||
crypto_spi_ctx_template_t em_encr_templ;
|
||||
crypto_spi_ctx_template_t em_mac_templ;
|
||||
} kcf_encrypt_mac_ops_params_t;
|
||||
|
||||
typedef struct kcf_mac_decrypt_ops_params {
|
||||
crypto_session_id_t md_sid;
|
||||
crypto_mech_type_t md_framework_mac_mechtype;
|
||||
crypto_mechanism_t md_mac_mech;
|
||||
crypto_key_t *md_mac_key;
|
||||
crypto_mech_type_t md_framework_decr_mechtype;
|
||||
crypto_mechanism_t md_decr_mech;
|
||||
crypto_key_t *md_decr_key;
|
||||
crypto_dual_data_t *md_ciphertext;
|
||||
crypto_data_t *md_mac;
|
||||
crypto_data_t *md_plaintext;
|
||||
crypto_spi_ctx_template_t md_mac_templ;
|
||||
crypto_spi_ctx_template_t md_decr_templ;
|
||||
} kcf_mac_decrypt_ops_params_t;
|
||||
|
||||
typedef struct kcf_random_number_ops_params {
|
||||
crypto_session_id_t rn_sid;
|
||||
uchar_t *rn_buf;
|
||||
size_t rn_buflen;
|
||||
uint_t rn_entropy_est;
|
||||
uint32_t rn_flags;
|
||||
} kcf_random_number_ops_params_t;
|
||||
|
||||
/*
|
||||
* so_pd is useful when the provider descriptor (pd) supplying the
|
||||
* provider handle is different from the pd supplying the ops vector.
|
||||
* This is the case for session open/close where so_pd can be the pd
|
||||
* of a logical provider. The pd supplying the ops vector is passed
|
||||
* as an argument to kcf_submit_request().
|
||||
*/
|
||||
typedef struct kcf_session_ops_params {
|
||||
crypto_session_id_t *so_sid_ptr;
|
||||
crypto_session_id_t so_sid;
|
||||
crypto_user_type_t so_user_type;
|
||||
char *so_pin;
|
||||
size_t so_pin_len;
|
||||
kcf_provider_desc_t *so_pd;
|
||||
} kcf_session_ops_params_t;
|
||||
|
||||
typedef struct kcf_object_ops_params {
|
||||
crypto_session_id_t oo_sid;
|
||||
crypto_object_id_t oo_object_id;
|
||||
crypto_object_attribute_t *oo_template;
|
||||
uint_t oo_attribute_count;
|
||||
crypto_object_id_t *oo_object_id_ptr;
|
||||
size_t *oo_object_size;
|
||||
void **oo_find_init_pp_ptr;
|
||||
void *oo_find_pp;
|
||||
uint_t oo_max_object_count;
|
||||
uint_t *oo_object_count_ptr;
|
||||
} kcf_object_ops_params_t;
|
||||
|
||||
/*
|
||||
* ko_key is used to encode wrapping key in key_wrap() and
|
||||
* unwrapping key in key_unwrap(). ko_key_template and
|
||||
* ko_key_attribute_count are used to encode public template
|
||||
* and public template attr count in key_generate_pair().
|
||||
* kops->ko_key_object_id_ptr is used to encode public key
|
||||
* in key_generate_pair().
|
||||
*/
|
||||
typedef struct kcf_key_ops_params {
|
||||
crypto_session_id_t ko_sid;
|
||||
crypto_mech_type_t ko_framework_mechtype;
|
||||
crypto_mechanism_t ko_mech;
|
||||
crypto_object_attribute_t *ko_key_template;
|
||||
uint_t ko_key_attribute_count;
|
||||
crypto_object_id_t *ko_key_object_id_ptr;
|
||||
crypto_object_attribute_t *ko_private_key_template;
|
||||
uint_t ko_private_key_attribute_count;
|
||||
crypto_object_id_t *ko_private_key_object_id_ptr;
|
||||
crypto_key_t *ko_key;
|
||||
uchar_t *ko_wrapped_key;
|
||||
size_t *ko_wrapped_key_len_ptr;
|
||||
crypto_object_attribute_t *ko_out_template1;
|
||||
crypto_object_attribute_t *ko_out_template2;
|
||||
uint_t ko_out_attribute_count1;
|
||||
uint_t ko_out_attribute_count2;
|
||||
} kcf_key_ops_params_t;
|
||||
|
||||
/*
|
||||
* po_pin and po_pin_len are used to encode new_pin and new_pin_len
|
||||
* when wrapping set_pin() function parameters.
|
||||
*
|
||||
* po_pd is useful when the provider descriptor (pd) supplying the
|
||||
* provider handle is different from the pd supplying the ops vector.
|
||||
* This is true for the ext_info provider entry point where po_pd
|
||||
* can be the pd of a logical provider. The pd supplying the ops vector
|
||||
* is passed as an argument to kcf_submit_request().
|
||||
*/
|
||||
typedef struct kcf_provmgmt_ops_params {
|
||||
crypto_session_id_t po_sid;
|
||||
char *po_pin;
|
||||
size_t po_pin_len;
|
||||
char *po_old_pin;
|
||||
size_t po_old_pin_len;
|
||||
char *po_label;
|
||||
crypto_provider_ext_info_t *po_ext_info;
|
||||
kcf_provider_desc_t *po_pd;
|
||||
} kcf_provmgmt_ops_params_t;
|
||||
|
||||
/*
|
||||
* The operation type within a function group.
|
||||
*/
|
||||
typedef enum kcf_op_type {
|
||||
/* common ops for all mechanisms */
|
||||
KCF_OP_INIT = 1,
|
||||
KCF_OP_SINGLE, /* pkcs11 sense. So, INIT is already done */
|
||||
KCF_OP_UPDATE,
|
||||
KCF_OP_FINAL,
|
||||
KCF_OP_ATOMIC,
|
||||
|
||||
/* digest_key op */
|
||||
KCF_OP_DIGEST_KEY,
|
||||
|
||||
/* mac specific op */
|
||||
KCF_OP_MAC_VERIFY_ATOMIC,
|
||||
|
||||
/* mac/cipher specific op */
|
||||
KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC,
|
||||
|
||||
/* sign_recover ops */
|
||||
KCF_OP_SIGN_RECOVER_INIT,
|
||||
KCF_OP_SIGN_RECOVER,
|
||||
KCF_OP_SIGN_RECOVER_ATOMIC,
|
||||
|
||||
/* verify_recover ops */
|
||||
KCF_OP_VERIFY_RECOVER_INIT,
|
||||
KCF_OP_VERIFY_RECOVER,
|
||||
KCF_OP_VERIFY_RECOVER_ATOMIC,
|
||||
|
||||
/* random number ops */
|
||||
KCF_OP_RANDOM_SEED,
|
||||
KCF_OP_RANDOM_GENERATE,
|
||||
|
||||
/* session management ops */
|
||||
KCF_OP_SESSION_OPEN,
|
||||
KCF_OP_SESSION_CLOSE,
|
||||
KCF_OP_SESSION_LOGIN,
|
||||
KCF_OP_SESSION_LOGOUT,
|
||||
|
||||
/* object management ops */
|
||||
KCF_OP_OBJECT_CREATE,
|
||||
KCF_OP_OBJECT_COPY,
|
||||
KCF_OP_OBJECT_DESTROY,
|
||||
KCF_OP_OBJECT_GET_SIZE,
|
||||
KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE,
|
||||
KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE,
|
||||
KCF_OP_OBJECT_FIND_INIT,
|
||||
KCF_OP_OBJECT_FIND,
|
||||
KCF_OP_OBJECT_FIND_FINAL,
|
||||
|
||||
/* key management ops */
|
||||
KCF_OP_KEY_GENERATE,
|
||||
KCF_OP_KEY_GENERATE_PAIR,
|
||||
KCF_OP_KEY_WRAP,
|
||||
KCF_OP_KEY_UNWRAP,
|
||||
KCF_OP_KEY_DERIVE,
|
||||
KCF_OP_KEY_CHECK,
|
||||
|
||||
/* provider management ops */
|
||||
KCF_OP_MGMT_EXTINFO,
|
||||
KCF_OP_MGMT_INITTOKEN,
|
||||
KCF_OP_MGMT_INITPIN,
|
||||
KCF_OP_MGMT_SETPIN
|
||||
} kcf_op_type_t;
|
||||
|
||||
/*
|
||||
* The operation groups that need wrapping of parameters. This is somewhat
|
||||
* similar to the function group type in spi.h except that this also includes
|
||||
* all the functions that don't have a mechanism.
|
||||
*
|
||||
* The wrapper macros should never take these enum values as an argument.
|
||||
* Rather, they are assigned in the macro itself since they are known
|
||||
* from the macro name.
|
||||
*/
|
||||
typedef enum kcf_op_group {
|
||||
KCF_OG_DIGEST = 1,
|
||||
KCF_OG_MAC,
|
||||
KCF_OG_ENCRYPT,
|
||||
KCF_OG_DECRYPT,
|
||||
KCF_OG_SIGN,
|
||||
KCF_OG_VERIFY,
|
||||
KCF_OG_ENCRYPT_MAC,
|
||||
KCF_OG_MAC_DECRYPT,
|
||||
KCF_OG_RANDOM,
|
||||
KCF_OG_SESSION,
|
||||
KCF_OG_OBJECT,
|
||||
KCF_OG_KEY,
|
||||
KCF_OG_PROVMGMT,
|
||||
KCF_OG_NOSTORE_KEY
|
||||
} kcf_op_group_t;
|
||||
|
||||
/*
|
||||
* The kcf_op_type_t enum values used here should be only for those
|
||||
* operations for which there is a k-api routine in sys/crypto/api.h.
|
||||
*/
|
||||
#define IS_INIT_OP(ftype) ((ftype) == KCF_OP_INIT)
|
||||
#define IS_SINGLE_OP(ftype) ((ftype) == KCF_OP_SINGLE)
|
||||
#define IS_UPDATE_OP(ftype) ((ftype) == KCF_OP_UPDATE)
|
||||
#define IS_FINAL_OP(ftype) ((ftype) == KCF_OP_FINAL)
|
||||
#define IS_ATOMIC_OP(ftype) ( \
|
||||
(ftype) == KCF_OP_ATOMIC || (ftype) == KCF_OP_MAC_VERIFY_ATOMIC || \
|
||||
(ftype) == KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC || \
|
||||
(ftype) == KCF_OP_SIGN_RECOVER_ATOMIC || \
|
||||
(ftype) == KCF_OP_VERIFY_RECOVER_ATOMIC)
|
||||
|
||||
/*
|
||||
* Keep the parameters associated with a request around.
|
||||
* We need to pass them to the SPI.
|
||||
*/
|
||||
typedef struct kcf_req_params {
|
||||
kcf_op_group_t rp_opgrp;
|
||||
kcf_op_type_t rp_optype;
|
||||
|
||||
union {
|
||||
kcf_digest_ops_params_t digest_params;
|
||||
kcf_mac_ops_params_t mac_params;
|
||||
kcf_encrypt_ops_params_t encrypt_params;
|
||||
kcf_decrypt_ops_params_t decrypt_params;
|
||||
kcf_sign_ops_params_t sign_params;
|
||||
kcf_verify_ops_params_t verify_params;
|
||||
kcf_encrypt_mac_ops_params_t encrypt_mac_params;
|
||||
kcf_mac_decrypt_ops_params_t mac_decrypt_params;
|
||||
kcf_random_number_ops_params_t random_number_params;
|
||||
kcf_session_ops_params_t session_params;
|
||||
kcf_object_ops_params_t object_params;
|
||||
kcf_key_ops_params_t key_params;
|
||||
kcf_provmgmt_ops_params_t provmgmt_params;
|
||||
} rp_u;
|
||||
} kcf_req_params_t;
|
||||
|
||||
|
||||
/*
|
||||
* The ioctl/k-api code should bundle the parameters into a kcf_req_params_t
|
||||
* structure before calling a scheduler routine. The following macros are
|
||||
* available for that purpose.
|
||||
*
|
||||
* For the most part, the macro arguments closely correspond to the
|
||||
* function parameters. In some cases, we use generic names. The comments
|
||||
* for the structure should indicate these cases.
|
||||
*/
|
||||
#define KCF_WRAP_DIGEST_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _digest) { \
|
||||
kcf_digest_ops_params_t *dops = &(req)->rp_u.digest_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_DIGEST; \
|
||||
(req)->rp_optype = ftype; \
|
||||
dops->do_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
dops->do_mech = *mechp; \
|
||||
dops->do_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
dops->do_digest_key = _key; \
|
||||
dops->do_data = _data; \
|
||||
dops->do_digest = _digest; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_MAC_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _mac, _templ) { \
|
||||
kcf_mac_ops_params_t *mops = &(req)->rp_u.mac_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_MAC; \
|
||||
(req)->rp_optype = ftype; \
|
||||
mops->mo_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
mops->mo_mech = *mechp; \
|
||||
mops->mo_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
mops->mo_key = _key; \
|
||||
mops->mo_data = _data; \
|
||||
mops->mo_mac = _mac; \
|
||||
mops->mo_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_ENCRYPT_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_plaintext, _ciphertext, _templ) { \
|
||||
kcf_encrypt_ops_params_t *cops = &(req)->rp_u.encrypt_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_ENCRYPT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cops->eo_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
cops->eo_mech = *mechp; \
|
||||
cops->eo_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
cops->eo_key = _key; \
|
||||
cops->eo_plaintext = _plaintext; \
|
||||
cops->eo_ciphertext = _ciphertext; \
|
||||
cops->eo_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_DECRYPT_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_ciphertext, _plaintext, _templ) { \
|
||||
kcf_decrypt_ops_params_t *cops = &(req)->rp_u.decrypt_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_DECRYPT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cops->dop_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
cops->dop_mech = *mechp; \
|
||||
cops->dop_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
cops->dop_key = _key; \
|
||||
cops->dop_ciphertext = _ciphertext; \
|
||||
cops->dop_plaintext = _plaintext; \
|
||||
cops->dop_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_SIGN_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _signature, _templ) { \
|
||||
kcf_sign_ops_params_t *sops = &(req)->rp_u.sign_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_SIGN; \
|
||||
(req)->rp_optype = ftype; \
|
||||
sops->so_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
sops->so_mech = *mechp; \
|
||||
sops->so_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
sops->so_key = _key; \
|
||||
sops->so_data = _data; \
|
||||
sops->so_signature = _signature; \
|
||||
sops->so_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_VERIFY_OPS_PARAMS(req, ftype, _sid, _mech, _key, \
|
||||
_data, _signature, _templ) { \
|
||||
kcf_verify_ops_params_t *vops = &(req)->rp_u.verify_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_VERIFY; \
|
||||
(req)->rp_optype = ftype; \
|
||||
vops->vo_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
vops->vo_mech = *mechp; \
|
||||
vops->vo_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
vops->vo_key = _key; \
|
||||
vops->vo_data = _data; \
|
||||
vops->vo_signature = _signature; \
|
||||
vops->vo_templ = _templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(req, ftype, _sid, _encr_key, \
|
||||
_mac_key, _plaintext, _ciphertext, _mac, _encr_templ, _mac_templ) { \
|
||||
kcf_encrypt_mac_ops_params_t *cmops = &(req)->rp_u.encrypt_mac_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_ENCRYPT_MAC; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cmops->em_sid = _sid; \
|
||||
cmops->em_encr_key = _encr_key; \
|
||||
cmops->em_mac_key = _mac_key; \
|
||||
cmops->em_plaintext = _plaintext; \
|
||||
cmops->em_ciphertext = _ciphertext; \
|
||||
cmops->em_mac = _mac; \
|
||||
cmops->em_encr_templ = _encr_templ; \
|
||||
cmops->em_mac_templ = _mac_templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(req, ftype, _sid, _mac_key, \
|
||||
_decr_key, _ciphertext, _mac, _plaintext, _mac_templ, _decr_templ) { \
|
||||
kcf_mac_decrypt_ops_params_t *cmops = &(req)->rp_u.mac_decrypt_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_MAC_DECRYPT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
cmops->md_sid = _sid; \
|
||||
cmops->md_mac_key = _mac_key; \
|
||||
cmops->md_decr_key = _decr_key; \
|
||||
cmops->md_ciphertext = _ciphertext; \
|
||||
cmops->md_mac = _mac; \
|
||||
cmops->md_plaintext = _plaintext; \
|
||||
cmops->md_mac_templ = _mac_templ; \
|
||||
cmops->md_decr_templ = _decr_templ; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_RANDOM_OPS_PARAMS(req, ftype, _sid, _buf, _buflen, \
|
||||
_est, _flags) { \
|
||||
kcf_random_number_ops_params_t *rops = \
|
||||
&(req)->rp_u.random_number_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_RANDOM; \
|
||||
(req)->rp_optype = ftype; \
|
||||
rops->rn_sid = _sid; \
|
||||
rops->rn_buf = _buf; \
|
||||
rops->rn_buflen = _buflen; \
|
||||
rops->rn_entropy_est = _est; \
|
||||
rops->rn_flags = _flags; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_SESSION_OPS_PARAMS(req, ftype, _sid_ptr, _sid, \
|
||||
_user_type, _pin, _pin_len, _pd) { \
|
||||
kcf_session_ops_params_t *sops = &(req)->rp_u.session_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_SESSION; \
|
||||
(req)->rp_optype = ftype; \
|
||||
sops->so_sid_ptr = _sid_ptr; \
|
||||
sops->so_sid = _sid; \
|
||||
sops->so_user_type = _user_type; \
|
||||
sops->so_pin = _pin; \
|
||||
sops->so_pin_len = _pin_len; \
|
||||
sops->so_pd = _pd; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_OBJECT_OPS_PARAMS(req, ftype, _sid, _object_id, \
|
||||
_template, _attribute_count, _object_id_ptr, _object_size, \
|
||||
_find_init_pp_ptr, _find_pp, _max_object_count, _object_count_ptr) { \
|
||||
kcf_object_ops_params_t *jops = &(req)->rp_u.object_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_OBJECT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
jops->oo_sid = _sid; \
|
||||
jops->oo_object_id = _object_id; \
|
||||
jops->oo_template = _template; \
|
||||
jops->oo_attribute_count = _attribute_count; \
|
||||
jops->oo_object_id_ptr = _object_id_ptr; \
|
||||
jops->oo_object_size = _object_size; \
|
||||
jops->oo_find_init_pp_ptr = _find_init_pp_ptr; \
|
||||
jops->oo_find_pp = _find_pp; \
|
||||
jops->oo_max_object_count = _max_object_count; \
|
||||
jops->oo_object_count_ptr = _object_count_ptr; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_KEY_OPS_PARAMS(req, ftype, _sid, _mech, _key_template, \
|
||||
_key_attribute_count, _key_object_id_ptr, _private_key_template, \
|
||||
_private_key_attribute_count, _private_key_object_id_ptr, \
|
||||
_key, _wrapped_key, _wrapped_key_len_ptr) { \
|
||||
kcf_key_ops_params_t *kops = &(req)->rp_u.key_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_KEY; \
|
||||
(req)->rp_optype = ftype; \
|
||||
kops->ko_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
kops->ko_mech = *mechp; \
|
||||
kops->ko_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
kops->ko_key_template = _key_template; \
|
||||
kops->ko_key_attribute_count = _key_attribute_count; \
|
||||
kops->ko_key_object_id_ptr = _key_object_id_ptr; \
|
||||
kops->ko_private_key_template = _private_key_template; \
|
||||
kops->ko_private_key_attribute_count = _private_key_attribute_count; \
|
||||
kops->ko_private_key_object_id_ptr = _private_key_object_id_ptr; \
|
||||
kops->ko_key = _key; \
|
||||
kops->ko_wrapped_key = _wrapped_key; \
|
||||
kops->ko_wrapped_key_len_ptr = _wrapped_key_len_ptr; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_PROVMGMT_OPS_PARAMS(req, ftype, _sid, _old_pin, \
|
||||
_old_pin_len, _pin, _pin_len, _label, _ext_info, _pd) { \
|
||||
kcf_provmgmt_ops_params_t *pops = &(req)->rp_u.provmgmt_params; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_PROVMGMT; \
|
||||
(req)->rp_optype = ftype; \
|
||||
pops->po_sid = _sid; \
|
||||
pops->po_pin = _pin; \
|
||||
pops->po_pin_len = _pin_len; \
|
||||
pops->po_old_pin = _old_pin; \
|
||||
pops->po_old_pin_len = _old_pin_len; \
|
||||
pops->po_label = _label; \
|
||||
pops->po_ext_info = _ext_info; \
|
||||
pops->po_pd = _pd; \
|
||||
}
|
||||
|
||||
#define KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(req, ftype, _sid, _mech, \
|
||||
_key_template, _key_attribute_count, _private_key_template, \
|
||||
_private_key_attribute_count, _key, _out_template1, \
|
||||
_out_attribute_count1, _out_template2, _out_attribute_count2) { \
|
||||
kcf_key_ops_params_t *kops = &(req)->rp_u.key_params; \
|
||||
crypto_mechanism_t *mechp = _mech; \
|
||||
\
|
||||
(req)->rp_opgrp = KCF_OG_NOSTORE_KEY; \
|
||||
(req)->rp_optype = ftype; \
|
||||
kops->ko_sid = _sid; \
|
||||
if (mechp != NULL) { \
|
||||
kops->ko_mech = *mechp; \
|
||||
kops->ko_framework_mechtype = mechp->cm_type; \
|
||||
} \
|
||||
kops->ko_key_template = _key_template; \
|
||||
kops->ko_key_attribute_count = _key_attribute_count; \
|
||||
kops->ko_key_object_id_ptr = NULL; \
|
||||
kops->ko_private_key_template = _private_key_template; \
|
||||
kops->ko_private_key_attribute_count = _private_key_attribute_count; \
|
||||
kops->ko_private_key_object_id_ptr = NULL; \
|
||||
kops->ko_key = _key; \
|
||||
kops->ko_wrapped_key = NULL; \
|
||||
kops->ko_wrapped_key_len_ptr = 0; \
|
||||
kops->ko_out_template1 = _out_template1; \
|
||||
kops->ko_out_template2 = _out_template2; \
|
||||
kops->ko_out_attribute_count1 = _out_attribute_count1; \
|
||||
kops->ko_out_attribute_count2 = _out_attribute_count2; \
|
||||
}
|
||||
|
||||
#define KCF_SET_PROVIDER_MECHNUM(fmtype, pd, mechp) \
|
||||
(mechp)->cm_type = \
|
||||
KCF_TO_PROV_MECHNUM(pd, fmtype);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_OPS_IMPL_H */
|
||||
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_SCHED_IMPL_H
|
||||
#define _SYS_CRYPTO_SCHED_IMPL_H
|
||||
|
||||
/*
|
||||
* Scheduler internal structures.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/api.h>
|
||||
#include <sys/crypto/spi.h>
|
||||
#include <sys/crypto/impl.h>
|
||||
#include <sys/crypto/common.h>
|
||||
#include <sys/crypto/ops_impl.h>
|
||||
|
||||
typedef void (kcf_func_t)(void *, int);
|
||||
|
||||
typedef enum kcf_req_status {
|
||||
REQ_ALLOCATED = 1,
|
||||
REQ_WAITING, /* At the framework level */
|
||||
REQ_INPROGRESS, /* At the provider level */
|
||||
REQ_DONE,
|
||||
REQ_CANCELED
|
||||
} kcf_req_status_t;
|
||||
|
||||
typedef enum kcf_call_type {
|
||||
CRYPTO_SYNCH = 1,
|
||||
CRYPTO_ASYNCH
|
||||
} kcf_call_type_t;
|
||||
|
||||
#define CHECK_RESTRICT(crq) (crq != NULL && \
|
||||
((crq)->cr_flag & CRYPTO_RESTRICTED))
|
||||
|
||||
#define CHECK_RESTRICT_FALSE B_FALSE
|
||||
|
||||
#define CHECK_FASTPATH(crq, pd) ((crq) == NULL || \
|
||||
!((crq)->cr_flag & CRYPTO_ALWAYS_QUEUE)) && \
|
||||
(pd)->pd_prov_type == CRYPTO_SW_PROVIDER
|
||||
|
||||
#define KCF_KMFLAG(crq) (((crq) == NULL) ? KM_SLEEP : KM_NOSLEEP)
|
||||
|
||||
/*
|
||||
* The framework keeps an internal handle to use in the adaptive
|
||||
* asynchronous case. This is the case when a client has the
|
||||
* CRYPTO_ALWAYS_QUEUE bit clear and a software provider is used for
|
||||
* the request. The request is completed in the context of the calling
|
||||
* thread and kernel memory must be allocated with KM_NOSLEEP.
|
||||
*
|
||||
* The framework passes a pointer to the handle in crypto_req_handle_t
|
||||
* argument when it calls the SPI of the software provider. The macros
|
||||
* KCF_RHNDL() and KCF_SWFP_RHNDL() are used to do this.
|
||||
*
|
||||
* When a provider asks the framework for kmflag value via
|
||||
* crypto_kmflag(9S) we use REQHNDL2_KMFLAG() macro.
|
||||
*/
|
||||
extern ulong_t kcf_swprov_hndl;
|
||||
#define KCF_RHNDL(kmflag) (((kmflag) == KM_SLEEP) ? NULL : &kcf_swprov_hndl)
|
||||
#define KCF_SWFP_RHNDL(crq) (((crq) == NULL) ? NULL : &kcf_swprov_hndl)
|
||||
#define REQHNDL2_KMFLAG(rhndl) \
|
||||
((rhndl == &kcf_swprov_hndl) ? KM_NOSLEEP : KM_SLEEP)
|
||||
|
||||
/* Internal call_req flags. They start after the public ones in api.h */
|
||||
|
||||
#define CRYPTO_SETDUAL 0x00001000 /* Set the 'cont' boolean before */
|
||||
/* submitting the request */
|
||||
#define KCF_ISDUALREQ(crq) \
|
||||
(((crq) == NULL) ? B_FALSE : (crq->cr_flag & CRYPTO_SETDUAL))
|
||||
|
||||
typedef struct kcf_prov_tried {
|
||||
kcf_provider_desc_t *pt_pd;
|
||||
struct kcf_prov_tried *pt_next;
|
||||
} kcf_prov_tried_t;
|
||||
|
||||
#define IS_FG_SUPPORTED(mdesc, fg) \
|
||||
(((mdesc)->pm_mech_info.cm_func_group_mask & (fg)) != 0)
|
||||
|
||||
#define IS_PROVIDER_TRIED(pd, tlist) \
|
||||
(tlist != NULL && is_in_triedlist(pd, tlist))
|
||||
|
||||
#define IS_RECOVERABLE(error) \
|
||||
(error == CRYPTO_BUFFER_TOO_BIG || \
|
||||
error == CRYPTO_BUSY || \
|
||||
error == CRYPTO_DEVICE_ERROR || \
|
||||
error == CRYPTO_DEVICE_MEMORY || \
|
||||
error == CRYPTO_KEY_SIZE_RANGE || \
|
||||
error == CRYPTO_NO_PERMISSION)
|
||||
|
||||
#define KCF_ATOMIC_INCR(x) atomic_add_32(&(x), 1)
|
||||
#define KCF_ATOMIC_DECR(x) atomic_add_32(&(x), -1)
|
||||
|
||||
/*
|
||||
* Node structure for synchronous requests.
|
||||
*/
|
||||
typedef struct kcf_sreq_node {
|
||||
/* Should always be the first field in this structure */
|
||||
kcf_call_type_t sn_type;
|
||||
/*
|
||||
* sn_cv and sr_lock are used to wait for the
|
||||
* operation to complete. sn_lock also protects
|
||||
* the sn_state field.
|
||||
*/
|
||||
kcondvar_t sn_cv;
|
||||
kmutex_t sn_lock;
|
||||
kcf_req_status_t sn_state;
|
||||
|
||||
/*
|
||||
* Return value from the operation. This will be
|
||||
* one of the CRYPTO_* errors defined in common.h.
|
||||
*/
|
||||
int sn_rv;
|
||||
|
||||
/*
|
||||
* parameters to call the SPI with. This can be
|
||||
* a pointer as we know the caller context/stack stays.
|
||||
*/
|
||||
struct kcf_req_params *sn_params;
|
||||
|
||||
/* Internal context for this request */
|
||||
struct kcf_context *sn_context;
|
||||
|
||||
/* Provider handling this request */
|
||||
kcf_provider_desc_t *sn_provider;
|
||||
} kcf_sreq_node_t;
|
||||
|
||||
/*
|
||||
* Node structure for asynchronous requests. A node can be on
|
||||
* on a chain of requests hanging of the internal context
|
||||
* structure and can be in the global software provider queue.
|
||||
*/
|
||||
typedef struct kcf_areq_node {
|
||||
/* Should always be the first field in this structure */
|
||||
kcf_call_type_t an_type;
|
||||
|
||||
/* an_lock protects the field an_state */
|
||||
kmutex_t an_lock;
|
||||
kcf_req_status_t an_state;
|
||||
crypto_call_req_t an_reqarg;
|
||||
|
||||
/*
|
||||
* parameters to call the SPI with. We need to
|
||||
* save the params since the caller stack can go away.
|
||||
*/
|
||||
struct kcf_req_params an_params;
|
||||
|
||||
/*
|
||||
* The next two fields should be NULL for operations that
|
||||
* don't need a context.
|
||||
*/
|
||||
/* Internal context for this request */
|
||||
struct kcf_context *an_context;
|
||||
|
||||
/* next in chain of requests for context */
|
||||
struct kcf_areq_node *an_ctxchain_next;
|
||||
|
||||
kcondvar_t an_turn_cv;
|
||||
boolean_t an_is_my_turn;
|
||||
boolean_t an_isdual; /* for internal reuse */
|
||||
|
||||
/*
|
||||
* Next and previous nodes in the global software
|
||||
* queue. These fields are NULL for a hardware
|
||||
* provider since we use a taskq there.
|
||||
*/
|
||||
struct kcf_areq_node *an_next;
|
||||
struct kcf_areq_node *an_prev;
|
||||
|
||||
/* Provider handling this request */
|
||||
kcf_provider_desc_t *an_provider;
|
||||
kcf_prov_tried_t *an_tried_plist;
|
||||
|
||||
struct kcf_areq_node *an_idnext; /* Next in ID hash */
|
||||
struct kcf_areq_node *an_idprev; /* Prev in ID hash */
|
||||
kcondvar_t an_done; /* Signal request completion */
|
||||
uint_t an_refcnt;
|
||||
} kcf_areq_node_t;
|
||||
|
||||
#define KCF_AREQ_REFHOLD(areq) { \
|
||||
atomic_add_32(&(areq)->an_refcnt, 1); \
|
||||
ASSERT((areq)->an_refcnt != 0); \
|
||||
}
|
||||
|
||||
#define KCF_AREQ_REFRELE(areq) { \
|
||||
ASSERT((areq)->an_refcnt != 0); \
|
||||
membar_exit(); \
|
||||
if (atomic_add_32_nv(&(areq)->an_refcnt, -1) == 0) \
|
||||
kcf_free_req(areq); \
|
||||
}
|
||||
|
||||
#define GET_REQ_TYPE(arg) *((kcf_call_type_t *)(arg))
|
||||
|
||||
#define NOTIFY_CLIENT(areq, err) (*(areq)->an_reqarg.cr_callback_func)(\
|
||||
(areq)->an_reqarg.cr_callback_arg, err);
|
||||
|
||||
/* For internally generated call requests for dual operations */
|
||||
typedef struct kcf_call_req {
|
||||
crypto_call_req_t kr_callreq; /* external client call req */
|
||||
kcf_req_params_t kr_params; /* Params saved for next call */
|
||||
kcf_areq_node_t *kr_areq; /* Use this areq */
|
||||
off_t kr_saveoffset;
|
||||
size_t kr_savelen;
|
||||
} kcf_dual_req_t;
|
||||
|
||||
/*
|
||||
* The following are some what similar to macros in callo.h, which implement
|
||||
* callout tables.
|
||||
*
|
||||
* The lower four bits of the ID are used to encode the table ID to
|
||||
* index in to. The REQID_COUNTER_HIGH bit is used to avoid any check for
|
||||
* wrap around when generating ID. We assume that there won't be a request
|
||||
* which takes more time than 2^^(sizeof (long) - 5) other requests submitted
|
||||
* after it. This ensures there won't be any ID collision.
|
||||
*/
|
||||
#define REQID_COUNTER_HIGH (1UL << (8 * sizeof (long) - 1))
|
||||
#define REQID_COUNTER_SHIFT 4
|
||||
#define REQID_COUNTER_LOW (1 << REQID_COUNTER_SHIFT)
|
||||
#define REQID_TABLES 16
|
||||
#define REQID_TABLE_MASK (REQID_TABLES - 1)
|
||||
|
||||
#define REQID_BUCKETS 512
|
||||
#define REQID_BUCKET_MASK (REQID_BUCKETS - 1)
|
||||
#define REQID_HASH(id) (((id) >> REQID_COUNTER_SHIFT) & REQID_BUCKET_MASK)
|
||||
|
||||
#define GET_REQID(areq) (areq)->an_reqarg.cr_reqid
|
||||
#define SET_REQID(areq, val) GET_REQID(areq) = val
|
||||
|
||||
/*
|
||||
* Hash table for async requests.
|
||||
*/
|
||||
typedef struct kcf_reqid_table {
|
||||
kmutex_t rt_lock;
|
||||
crypto_req_id_t rt_curid;
|
||||
kcf_areq_node_t *rt_idhash[REQID_BUCKETS];
|
||||
} kcf_reqid_table_t;
|
||||
|
||||
/*
|
||||
* Global software provider queue structure. Requests to be
|
||||
* handled by a SW provider and have the ALWAYS_QUEUE flag set
|
||||
* get queued here.
|
||||
*/
|
||||
typedef struct kcf_global_swq {
|
||||
/*
|
||||
* gs_cv and gs_lock are used to wait for new requests.
|
||||
* gs_lock protects the changes to the queue.
|
||||
*/
|
||||
kcondvar_t gs_cv;
|
||||
kmutex_t gs_lock;
|
||||
uint_t gs_njobs;
|
||||
uint_t gs_maxjobs;
|
||||
kcf_areq_node_t *gs_first;
|
||||
kcf_areq_node_t *gs_last;
|
||||
} kcf_global_swq_t;
|
||||
|
||||
|
||||
/*
|
||||
* Internal representation of a canonical context. We contain crypto_ctx_t
|
||||
* structure in order to have just one memory allocation. The SPI
|
||||
* ((crypto_ctx_t *)ctx)->cc_framework_private maps to this structure.
|
||||
*/
|
||||
typedef struct kcf_context {
|
||||
crypto_ctx_t kc_glbl_ctx;
|
||||
uint_t kc_refcnt;
|
||||
kmutex_t kc_in_use_lock;
|
||||
/*
|
||||
* kc_req_chain_first and kc_req_chain_last are used to chain
|
||||
* multiple async requests using the same context. They should be
|
||||
* NULL for sync requests.
|
||||
*/
|
||||
kcf_areq_node_t *kc_req_chain_first;
|
||||
kcf_areq_node_t *kc_req_chain_last;
|
||||
kcf_provider_desc_t *kc_prov_desc; /* Prov. descriptor */
|
||||
kcf_provider_desc_t *kc_sw_prov_desc; /* Prov. descriptor */
|
||||
kcf_mech_entry_t *kc_mech;
|
||||
struct kcf_context *kc_secondctx; /* for dual contexts */
|
||||
} kcf_context_t;
|
||||
|
||||
/*
|
||||
* Bump up the reference count on the framework private context. A
|
||||
* global context or a request that references this structure should
|
||||
* do a hold.
|
||||
*/
|
||||
#define KCF_CONTEXT_REFHOLD(ictx) { \
|
||||
atomic_add_32(&(ictx)->kc_refcnt, 1); \
|
||||
ASSERT((ictx)->kc_refcnt != 0); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrement the reference count on the framework private context.
|
||||
* When the last reference is released, the framework private
|
||||
* context structure is freed along with the global context.
|
||||
*/
|
||||
#define KCF_CONTEXT_REFRELE(ictx) { \
|
||||
ASSERT((ictx)->kc_refcnt != 0); \
|
||||
membar_exit(); \
|
||||
if (atomic_add_32_nv(&(ictx)->kc_refcnt, -1) == 0) \
|
||||
kcf_free_context(ictx); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we can release the context now. In case of CRYPTO_QUEUED
|
||||
* we do not release it as we can do it only after the provider notified
|
||||
* us. In case of CRYPTO_BUSY, the client can retry the request using
|
||||
* the context, so we do not release the context.
|
||||
*
|
||||
* This macro should be called only from the final routine in
|
||||
* an init/update/final sequence. We do not release the context in case
|
||||
* of update operations. We require the consumer to free it
|
||||
* explicitly, in case it wants to abandon the operation. This is done
|
||||
* as there may be mechanisms in ECB mode that can continue even if
|
||||
* an operation on a block fails.
|
||||
*/
|
||||
#define KCF_CONTEXT_COND_RELEASE(rv, kcf_ctx) { \
|
||||
if (KCF_CONTEXT_DONE(rv)) \
|
||||
KCF_CONTEXT_REFRELE(kcf_ctx); \
|
||||
}
|
||||
|
||||
/*
|
||||
* This macro determines whether we're done with a context.
|
||||
*/
|
||||
#define KCF_CONTEXT_DONE(rv) \
|
||||
((rv) != CRYPTO_QUEUED && (rv) != CRYPTO_BUSY && \
|
||||
(rv) != CRYPTO_BUFFER_TOO_SMALL)
|
||||
|
||||
/*
|
||||
* A crypto_ctx_template_t is internally a pointer to this struct
|
||||
*/
|
||||
typedef struct kcf_ctx_template {
|
||||
crypto_kcf_provider_handle_t ct_prov_handle; /* provider handle */
|
||||
uint_t ct_generation; /* generation # */
|
||||
size_t ct_size; /* for freeing */
|
||||
crypto_spi_ctx_template_t ct_prov_tmpl; /* context template */
|
||||
/* from the SW prov */
|
||||
} kcf_ctx_template_t;
|
||||
|
||||
/*
|
||||
* Structure for pool of threads working on global software queue.
|
||||
*/
|
||||
typedef struct kcf_pool {
|
||||
uint32_t kp_threads; /* Number of threads in pool */
|
||||
uint32_t kp_idlethreads; /* Idle threads in pool */
|
||||
uint32_t kp_blockedthreads; /* Blocked threads in pool */
|
||||
|
||||
/*
|
||||
* cv & lock to monitor the condition when no threads
|
||||
* are around. In this case the failover thread kicks in.
|
||||
*/
|
||||
kcondvar_t kp_nothr_cv;
|
||||
kmutex_t kp_thread_lock;
|
||||
|
||||
/* Userspace thread creator variables. */
|
||||
boolean_t kp_signal_create_thread; /* Create requested flag */
|
||||
int kp_nthrs; /* # of threads to create */
|
||||
boolean_t kp_user_waiting; /* Thread waiting for work */
|
||||
|
||||
/*
|
||||
* cv & lock for the condition where more threads need to be
|
||||
* created. kp_user_lock also protects the three fileds above.
|
||||
*/
|
||||
kcondvar_t kp_user_cv; /* Creator cond. variable */
|
||||
kmutex_t kp_user_lock; /* Creator lock */
|
||||
} kcf_pool_t;
|
||||
|
||||
|
||||
/*
|
||||
* State of a crypto bufcall element.
|
||||
*/
|
||||
typedef enum cbuf_state {
|
||||
CBUF_FREE = 1,
|
||||
CBUF_WAITING,
|
||||
CBUF_RUNNING
|
||||
} cbuf_state_t;
|
||||
|
||||
/*
|
||||
* Structure of a crypto bufcall element.
|
||||
*/
|
||||
typedef struct kcf_cbuf_elem {
|
||||
/*
|
||||
* lock and cv to wait for CBUF_RUNNING to be done
|
||||
* kc_lock also protects kc_state.
|
||||
*/
|
||||
kmutex_t kc_lock;
|
||||
kcondvar_t kc_cv;
|
||||
cbuf_state_t kc_state;
|
||||
|
||||
struct kcf_cbuf_elem *kc_next;
|
||||
struct kcf_cbuf_elem *kc_prev;
|
||||
|
||||
void (*kc_func)(void *arg);
|
||||
void *kc_arg;
|
||||
} kcf_cbuf_elem_t;
|
||||
|
||||
/*
|
||||
* State of a notify element.
|
||||
*/
|
||||
typedef enum ntfy_elem_state {
|
||||
NTFY_WAITING = 1,
|
||||
NTFY_RUNNING
|
||||
} ntfy_elem_state_t;
|
||||
|
||||
/*
|
||||
* Structure of a notify list element.
|
||||
*/
|
||||
typedef struct kcf_ntfy_elem {
|
||||
/*
|
||||
* lock and cv to wait for NTFY_RUNNING to be done.
|
||||
* kn_lock also protects kn_state.
|
||||
*/
|
||||
kmutex_t kn_lock;
|
||||
kcondvar_t kn_cv;
|
||||
ntfy_elem_state_t kn_state;
|
||||
|
||||
struct kcf_ntfy_elem *kn_next;
|
||||
struct kcf_ntfy_elem *kn_prev;
|
||||
|
||||
crypto_notify_callback_t kn_func;
|
||||
uint32_t kn_event_mask;
|
||||
} kcf_ntfy_elem_t;
|
||||
|
||||
|
||||
/*
|
||||
* The following values are based on the assumption that it would
|
||||
* take around eight cpus to load a hardware provider (This is true for
|
||||
* at least one product) and a kernel client may come from different
|
||||
* low-priority interrupt levels. We will have CYRPTO_TASKQ_MIN number
|
||||
* of cached taskq entries. The CRYPTO_TASKQ_MAX number is based on
|
||||
* a throughput of 1GB/s using 512-byte buffers. These are just
|
||||
* reasonable estimates and might need to change in future.
|
||||
*/
|
||||
#define CRYPTO_TASKQ_THREADS 8
|
||||
#define CYRPTO_TASKQ_MIN 64
|
||||
#define CRYPTO_TASKQ_MAX 2 * 1024 * 1024
|
||||
|
||||
extern int crypto_taskq_threads;
|
||||
extern int crypto_taskq_minalloc;
|
||||
extern int crypto_taskq_maxalloc;
|
||||
extern kcf_global_swq_t *gswq;
|
||||
extern int kcf_maxthreads;
|
||||
extern int kcf_minthreads;
|
||||
|
||||
/*
|
||||
* All pending crypto bufcalls are put on a list. cbuf_list_lock
|
||||
* protects changes to this list.
|
||||
*/
|
||||
extern kmutex_t cbuf_list_lock;
|
||||
extern kcondvar_t cbuf_list_cv;
|
||||
|
||||
/*
|
||||
* All event subscribers are put on a list. kcf_notify_list_lock
|
||||
* protects changes to this list.
|
||||
*/
|
||||
extern kmutex_t ntfy_list_lock;
|
||||
extern kcondvar_t ntfy_list_cv;
|
||||
|
||||
boolean_t kcf_get_next_logical_provider_member(kcf_provider_desc_t *,
|
||||
kcf_provider_desc_t *, kcf_provider_desc_t **);
|
||||
extern int kcf_get_hardware_provider(crypto_mech_type_t, crypto_mech_type_t,
|
||||
boolean_t, kcf_provider_desc_t *, kcf_provider_desc_t **,
|
||||
crypto_func_group_t);
|
||||
extern int kcf_get_hardware_provider_nomech(offset_t, offset_t,
|
||||
boolean_t, kcf_provider_desc_t *, kcf_provider_desc_t **);
|
||||
extern void kcf_free_triedlist(kcf_prov_tried_t *);
|
||||
extern kcf_prov_tried_t *kcf_insert_triedlist(kcf_prov_tried_t **,
|
||||
kcf_provider_desc_t *, int);
|
||||
extern kcf_provider_desc_t *kcf_get_mech_provider(crypto_mech_type_t,
|
||||
kcf_mech_entry_t **, int *, kcf_prov_tried_t *, crypto_func_group_t,
|
||||
boolean_t, size_t);
|
||||
extern kcf_provider_desc_t *kcf_get_dual_provider(crypto_mechanism_t *,
|
||||
crypto_mechanism_t *, kcf_mech_entry_t **, crypto_mech_type_t *,
|
||||
crypto_mech_type_t *, int *, kcf_prov_tried_t *,
|
||||
crypto_func_group_t, crypto_func_group_t, boolean_t, size_t);
|
||||
extern crypto_ctx_t *kcf_new_ctx(crypto_call_req_t *, kcf_provider_desc_t *,
|
||||
crypto_session_id_t);
|
||||
extern int kcf_submit_request(kcf_provider_desc_t *, crypto_ctx_t *,
|
||||
crypto_call_req_t *, kcf_req_params_t *, boolean_t);
|
||||
extern void kcf_sched_destroy(void);
|
||||
extern void kcf_sched_init(void);
|
||||
extern void kcf_sched_start(void);
|
||||
extern void kcf_sop_done(kcf_sreq_node_t *, int);
|
||||
extern void kcf_aop_done(kcf_areq_node_t *, int);
|
||||
extern int common_submit_request(kcf_provider_desc_t *,
|
||||
crypto_ctx_t *, kcf_req_params_t *, crypto_req_handle_t);
|
||||
extern void kcf_free_context(kcf_context_t *);
|
||||
|
||||
extern int kcf_svc_wait(int *);
|
||||
extern int kcf_svc_do_run(void);
|
||||
extern int kcf_need_signature_verification(kcf_provider_desc_t *);
|
||||
extern void kcf_verify_signature(void *);
|
||||
extern struct modctl *kcf_get_modctl(crypto_provider_info_t *);
|
||||
extern void verify_unverified_providers(void);
|
||||
extern void kcf_free_req(kcf_areq_node_t *areq);
|
||||
extern void crypto_bufcall_service(void);
|
||||
|
||||
extern void kcf_walk_ntfylist(uint32_t, void *);
|
||||
extern void kcf_do_notify(kcf_provider_desc_t *, boolean_t);
|
||||
|
||||
extern kcf_dual_req_t *kcf_alloc_req(crypto_call_req_t *);
|
||||
extern void kcf_next_req(void *, int);
|
||||
extern void kcf_last_req(void *, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_SCHED_IMPL_H */
|
||||
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CRYPTO_SPI_H
|
||||
#define _SYS_CRYPTO_SPI_H
|
||||
|
||||
/*
|
||||
* CSPI: Cryptographic Service Provider Interface.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/crypto/common.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define CRYPTO_SPI_VERSION_1 1
|
||||
#define CRYPTO_SPI_VERSION_2 2
|
||||
#define CRYPTO_SPI_VERSION_3 3
|
||||
|
||||
/*
|
||||
* Provider-private handle. This handle is specified by a provider
|
||||
* when it registers by means of the pi_provider_handle field of
|
||||
* the crypto_provider_info structure, and passed to the provider
|
||||
* when its entry points are invoked.
|
||||
*/
|
||||
typedef void *crypto_provider_handle_t;
|
||||
|
||||
/*
|
||||
* Context templates can be used to by software providers to pre-process
|
||||
* keying material, such as key schedules. They are allocated by
|
||||
* a software provider create_ctx_template(9E) entry point, and passed
|
||||
* as argument to initialization and atomic provider entry points.
|
||||
*/
|
||||
typedef void *crypto_spi_ctx_template_t;
|
||||
|
||||
/*
|
||||
* Request handles are used by the kernel to identify an asynchronous
|
||||
* request being processed by a provider. It is passed by the kernel
|
||||
* to a hardware provider when submitting a request, and must be
|
||||
* specified by a provider when calling crypto_op_notification(9F)
|
||||
*/
|
||||
typedef void *crypto_req_handle_t;
|
||||
|
||||
/* Values for cc_flags field */
|
||||
#define CRYPTO_INIT_OPSTATE 0x00000001 /* allocate and init cc_opstate */
|
||||
#define CRYPTO_USE_OPSTATE 0x00000002 /* .. start using it as context */
|
||||
|
||||
/*
|
||||
* The context structure is passed from the kernel to a provider.
|
||||
* It contains the information needed to process a multi-part or
|
||||
* single part operation. The context structure is not used
|
||||
* by atomic operations.
|
||||
*
|
||||
* Parameters needed to perform a cryptographic operation, such
|
||||
* as keys, mechanisms, input and output buffers, are passed
|
||||
* as separate arguments to Provider routines.
|
||||
*/
|
||||
typedef struct crypto_ctx {
|
||||
crypto_provider_handle_t cc_provider;
|
||||
crypto_session_id_t cc_session;
|
||||
void *cc_provider_private; /* owned by provider */
|
||||
void *cc_framework_private; /* owned by framework */
|
||||
uint32_t cc_flags; /* flags */
|
||||
void *cc_opstate; /* state */
|
||||
} crypto_ctx_t;
|
||||
|
||||
/*
|
||||
* Extended provider information.
|
||||
*/
|
||||
|
||||
/*
|
||||
* valid values for ei_flags field of extended info structure
|
||||
* They match the RSA Security, Inc PKCS#11 tokenInfo flags.
|
||||
*/
|
||||
#define CRYPTO_EXTF_RNG 0x00000001
|
||||
#define CRYPTO_EXTF_WRITE_PROTECTED 0x00000002
|
||||
#define CRYPTO_EXTF_LOGIN_REQUIRED 0x00000004
|
||||
#define CRYPTO_EXTF_USER_PIN_INITIALIZED 0x00000008
|
||||
#define CRYPTO_EXTF_CLOCK_ON_TOKEN 0x00000040
|
||||
#define CRYPTO_EXTF_PROTECTED_AUTHENTICATION_PATH 0x00000100
|
||||
#define CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS 0x00000200
|
||||
#define CRYPTO_EXTF_TOKEN_INITIALIZED 0x00000400
|
||||
#define CRYPTO_EXTF_USER_PIN_COUNT_LOW 0x00010000
|
||||
#define CRYPTO_EXTF_USER_PIN_FINAL_TRY 0x00020000
|
||||
#define CRYPTO_EXTF_USER_PIN_LOCKED 0x00040000
|
||||
#define CRYPTO_EXTF_USER_PIN_TO_BE_CHANGED 0x00080000
|
||||
#define CRYPTO_EXTF_SO_PIN_COUNT_LOW 0x00100000
|
||||
#define CRYPTO_EXTF_SO_PIN_FINAL_TRY 0x00200000
|
||||
#define CRYPTO_EXTF_SO_PIN_LOCKED 0x00400000
|
||||
#define CRYPTO_EXTF_SO_PIN_TO_BE_CHANGED 0x00800000
|
||||
|
||||
/*
|
||||
* The crypto_control_ops structure contains pointers to control
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_control_ops {
|
||||
void (*provider_status)(crypto_provider_handle_t, uint_t *);
|
||||
} crypto_control_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_ctx_ops structure contains points to context and context
|
||||
* templates management operations for cryptographic providers. It is
|
||||
* passed through the crypto_ops(9S) structure when providers register
|
||||
* with the kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_ctx_ops {
|
||||
int (*create_ctx_template)(crypto_provider_handle_t,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t *, size_t *, crypto_req_handle_t);
|
||||
int (*free_context)(crypto_ctx_t *);
|
||||
} crypto_ctx_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_digest_ops structure contains pointers to digest
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_digest_ops {
|
||||
int (*digest_init)(crypto_ctx_t *, crypto_mechanism_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest)(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest_update)(crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest_key)(crypto_ctx_t *, crypto_key_t *, crypto_req_handle_t);
|
||||
int (*digest_final)(crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*digest_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
} crypto_digest_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_cipher_ops structure contains pointers to encryption
|
||||
* and decryption operations for cryptographic providers. It is
|
||||
* passed through the crypto_ops(9S) structure when providers register
|
||||
* with the kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_cipher_ops {
|
||||
int (*encrypt_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*encrypt)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
|
||||
int (*decrypt_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*decrypt)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
} crypto_cipher_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_mac_ops structure contains pointers to MAC
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_mac_ops {
|
||||
int (*mac_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*mac)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*mac_verify_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_mac_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_sign_ops structure contains pointers to signing
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_sign_ops {
|
||||
int (*sign_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*sign)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*sign_recover_init)(crypto_ctx_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*sign_recover)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_recover_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_sign_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_verify_ops structure contains pointers to verify
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_verify_ops {
|
||||
int (*verify_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*do_verify)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*verify_recover_init)(crypto_ctx_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
int (*verify_recover)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*verify_recover_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_verify_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_dual_ops structure contains pointers to dual
|
||||
* cipher and sign/verify operations for cryptographic providers.
|
||||
* It is passed through the crypto_ops(9S) structure when
|
||||
* providers register with the kernel using
|
||||
* crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_dual_ops {
|
||||
int (*digest_encrypt_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_digest_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*sign_encrypt_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
int (*decrypt_verify_update)(
|
||||
crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_req_handle_t);
|
||||
} crypto_dual_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_dual_cipher_mac_ops structure contains pointers to dual
|
||||
* cipher and MAC operations for cryptographic providers.
|
||||
* It is passed through the crypto_ops(9S) structure when
|
||||
* providers register with the kernel using
|
||||
* crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_dual_cipher_mac_ops {
|
||||
int (*encrypt_mac_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*encrypt_mac)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*encrypt_mac_update)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_mac_final)(crypto_ctx_t *,
|
||||
crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*encrypt_mac_atomic)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_data_t *, crypto_dual_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
|
||||
int (*mac_decrypt_init)(crypto_ctx_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
|
||||
crypto_key_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*mac_decrypt)(crypto_ctx_t *,
|
||||
crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*mac_decrypt_update)(crypto_ctx_t *,
|
||||
crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_decrypt_final)(crypto_ctx_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
|
||||
int (*mac_decrypt_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
int (*mac_verify_decrypt_atomic)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
|
||||
crypto_spi_ctx_template_t, crypto_req_handle_t);
|
||||
} crypto_dual_cipher_mac_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_random_number_ops structure contains pointers to random
|
||||
* number operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_random_number_ops {
|
||||
int (*seed_random)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
|
||||
int (*generate_random)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
uchar_t *, size_t, crypto_req_handle_t);
|
||||
} crypto_random_number_ops_t;
|
||||
|
||||
/*
|
||||
* Flag values for seed_random.
|
||||
*/
|
||||
#define CRYPTO_SEED_NOW 0x00000001
|
||||
|
||||
/*
|
||||
* The crypto_session_ops structure contains pointers to session
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_session_ops {
|
||||
int (*session_open)(crypto_provider_handle_t, crypto_session_id_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*session_close)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_req_handle_t);
|
||||
int (*session_login)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_user_type_t, char *, size_t, crypto_req_handle_t);
|
||||
int (*session_logout)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_req_handle_t);
|
||||
} crypto_session_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_object_ops structure contains pointers to object
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_object_ops {
|
||||
int (*object_create)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
|
||||
crypto_req_handle_t);
|
||||
int (*object_copy)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_id_t, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*object_destroy)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_id_t, crypto_req_handle_t);
|
||||
int (*object_get_size)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_id_t, size_t *, crypto_req_handle_t);
|
||||
int (*object_get_attribute_value)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_object_id_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
int (*object_set_attribute_value)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_object_id_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
int (*object_find_init)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_object_attribute_t *, uint_t, void **,
|
||||
crypto_req_handle_t);
|
||||
int (*object_find)(crypto_provider_handle_t, void *,
|
||||
crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
|
||||
int (*object_find_final)(crypto_provider_handle_t, void *,
|
||||
crypto_req_handle_t);
|
||||
} crypto_object_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_key_ops structure contains pointers to key
|
||||
* operations for cryptographic providers. It is passed through
|
||||
* the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_key_ops {
|
||||
int (*key_generate)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_generate_pair)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_wrap)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
|
||||
uchar_t *, size_t *, crypto_req_handle_t);
|
||||
int (*key_unwrap)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
|
||||
crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_derive)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
|
||||
uint_t, crypto_object_id_t *, crypto_req_handle_t);
|
||||
int (*key_check)(crypto_provider_handle_t, crypto_mechanism_t *,
|
||||
crypto_key_t *);
|
||||
} crypto_key_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_provider_management_ops structure contains pointers
|
||||
* to management operations for cryptographic providers. It is passed
|
||||
* through the crypto_ops(9S) structure when providers register with the
|
||||
* kernel using crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_provider_management_ops {
|
||||
int (*ext_info)(crypto_provider_handle_t,
|
||||
crypto_provider_ext_info_t *, crypto_req_handle_t);
|
||||
int (*init_token)(crypto_provider_handle_t, char *, size_t,
|
||||
char *, crypto_req_handle_t);
|
||||
int (*init_pin)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
char *, size_t, crypto_req_handle_t);
|
||||
int (*set_pin)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
char *, size_t, char *, size_t, crypto_req_handle_t);
|
||||
} crypto_provider_management_ops_t;
|
||||
|
||||
typedef struct crypto_mech_ops {
|
||||
int (*copyin_mechanism)(crypto_provider_handle_t,
|
||||
crypto_mechanism_t *, crypto_mechanism_t *, int *, int);
|
||||
int (*copyout_mechanism)(crypto_provider_handle_t,
|
||||
crypto_mechanism_t *, crypto_mechanism_t *, int *, int);
|
||||
int (*free_mechanism)(crypto_provider_handle_t, crypto_mechanism_t *);
|
||||
} crypto_mech_ops_t;
|
||||
|
||||
typedef struct crypto_nostore_key_ops {
|
||||
int (*nostore_key_generate)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
|
||||
uint_t, crypto_req_handle_t);
|
||||
int (*nostore_key_generate_pair)(crypto_provider_handle_t,
|
||||
crypto_session_id_t, crypto_mechanism_t *,
|
||||
crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
|
||||
uint_t, crypto_object_attribute_t *, uint_t,
|
||||
crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
int (*nostore_key_derive)(crypto_provider_handle_t, crypto_session_id_t,
|
||||
crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
|
||||
uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
|
||||
} crypto_nostore_key_ops_t;
|
||||
|
||||
/*
|
||||
* The crypto_ops(9S) structure contains the structures containing
|
||||
* the pointers to functions implemented by cryptographic providers.
|
||||
* It is specified as part of the crypto_provider_info(9S)
|
||||
* supplied by a provider when it registers with the kernel
|
||||
* by calling crypto_register_provider(9F).
|
||||
*/
|
||||
typedef struct crypto_ops_v1 {
|
||||
crypto_control_ops_t *co_control_ops;
|
||||
crypto_digest_ops_t *co_digest_ops;
|
||||
crypto_cipher_ops_t *co_cipher_ops;
|
||||
crypto_mac_ops_t *co_mac_ops;
|
||||
crypto_sign_ops_t *co_sign_ops;
|
||||
crypto_verify_ops_t *co_verify_ops;
|
||||
crypto_dual_ops_t *co_dual_ops;
|
||||
crypto_dual_cipher_mac_ops_t *co_dual_cipher_mac_ops;
|
||||
crypto_random_number_ops_t *co_random_ops;
|
||||
crypto_session_ops_t *co_session_ops;
|
||||
crypto_object_ops_t *co_object_ops;
|
||||
crypto_key_ops_t *co_key_ops;
|
||||
crypto_provider_management_ops_t *co_provider_ops;
|
||||
crypto_ctx_ops_t *co_ctx_ops;
|
||||
} crypto_ops_v1_t;
|
||||
|
||||
typedef struct crypto_ops_v2 {
|
||||
crypto_ops_v1_t v1_ops;
|
||||
crypto_mech_ops_t *co_mech_ops;
|
||||
} crypto_ops_v2_t;
|
||||
|
||||
typedef struct crypto_ops_v3 {
|
||||
crypto_ops_v2_t v2_ops;
|
||||
crypto_nostore_key_ops_t *co_nostore_key_ops;
|
||||
} crypto_ops_v3_t;
|
||||
|
||||
typedef struct crypto_ops {
|
||||
union {
|
||||
crypto_ops_v3_t cou_v3;
|
||||
crypto_ops_v2_t cou_v2;
|
||||
crypto_ops_v1_t cou_v1;
|
||||
} cou;
|
||||
} crypto_ops_t;
|
||||
|
||||
#define co_control_ops cou.cou_v1.co_control_ops
|
||||
#define co_digest_ops cou.cou_v1.co_digest_ops
|
||||
#define co_cipher_ops cou.cou_v1.co_cipher_ops
|
||||
#define co_mac_ops cou.cou_v1.co_mac_ops
|
||||
#define co_sign_ops cou.cou_v1.co_sign_ops
|
||||
#define co_verify_ops cou.cou_v1.co_verify_ops
|
||||
#define co_dual_ops cou.cou_v1.co_dual_ops
|
||||
#define co_dual_cipher_mac_ops cou.cou_v1.co_dual_cipher_mac_ops
|
||||
#define co_random_ops cou.cou_v1.co_random_ops
|
||||
#define co_session_ops cou.cou_v1.co_session_ops
|
||||
#define co_object_ops cou.cou_v1.co_object_ops
|
||||
#define co_key_ops cou.cou_v1.co_key_ops
|
||||
#define co_provider_ops cou.cou_v1.co_provider_ops
|
||||
#define co_ctx_ops cou.cou_v1.co_ctx_ops
|
||||
#define co_mech_ops cou.cou_v2.co_mech_ops
|
||||
#define co_nostore_key_ops cou.cou_v3.co_nostore_key_ops
|
||||
|
||||
/*
|
||||
* The mechanism info structure crypto_mech_info_t contains a function group
|
||||
* bit mask cm_func_group_mask. This field, of type crypto_func_group_t,
|
||||
* specifies the provider entry point that can be used a particular
|
||||
* mechanism. The function group mask is a combination of the following values.
|
||||
*/
|
||||
|
||||
typedef uint32_t crypto_func_group_t;
|
||||
|
||||
|
||||
#define CRYPTO_FG_ENCRYPT 0x00000001 /* encrypt_init() */
|
||||
#define CRYPTO_FG_DECRYPT 0x00000002 /* decrypt_init() */
|
||||
#define CRYPTO_FG_DIGEST 0x00000004 /* digest_init() */
|
||||
#define CRYPTO_FG_SIGN 0x00000008 /* sign_init() */
|
||||
#define CRYPTO_FG_SIGN_RECOVER 0x00000010 /* sign_recover_init() */
|
||||
#define CRYPTO_FG_VERIFY 0x00000020 /* verify_init() */
|
||||
#define CRYPTO_FG_VERIFY_RECOVER 0x00000040 /* verify_recover_init() */
|
||||
#define CRYPTO_FG_GENERATE 0x00000080 /* key_generate() */
|
||||
#define CRYPTO_FG_GENERATE_KEY_PAIR 0x00000100 /* key_generate_pair() */
|
||||
#define CRYPTO_FG_WRAP 0x00000200 /* key_wrap() */
|
||||
#define CRYPTO_FG_UNWRAP 0x00000400 /* key_unwrap() */
|
||||
#define CRYPTO_FG_DERIVE 0x00000800 /* key_derive() */
|
||||
#define CRYPTO_FG_MAC 0x00001000 /* mac_init() */
|
||||
#define CRYPTO_FG_ENCRYPT_MAC 0x00002000 /* encrypt_mac_init() */
|
||||
#define CRYPTO_FG_MAC_DECRYPT 0x00004000 /* decrypt_mac_init() */
|
||||
#define CRYPTO_FG_ENCRYPT_ATOMIC 0x00008000 /* encrypt_atomic() */
|
||||
#define CRYPTO_FG_DECRYPT_ATOMIC 0x00010000 /* decrypt_atomic() */
|
||||
#define CRYPTO_FG_MAC_ATOMIC 0x00020000 /* mac_atomic() */
|
||||
#define CRYPTO_FG_DIGEST_ATOMIC 0x00040000 /* digest_atomic() */
|
||||
#define CRYPTO_FG_SIGN_ATOMIC 0x00080000 /* sign_atomic() */
|
||||
#define CRYPTO_FG_SIGN_RECOVER_ATOMIC 0x00100000 /* sign_recover_atomic() */
|
||||
#define CRYPTO_FG_VERIFY_ATOMIC 0x00200000 /* verify_atomic() */
|
||||
#define CRYPTO_FG_VERIFY_RECOVER_ATOMIC 0x00400000 /* verify_recover_atomic() */
|
||||
#define CRYPTO_FG_ENCRYPT_MAC_ATOMIC 0x00800000 /* encrypt_mac_atomic() */
|
||||
#define CRYPTO_FG_MAC_DECRYPT_ATOMIC 0x01000000 /* mac_decrypt_atomic() */
|
||||
#define CRYPTO_FG_RESERVED 0x80000000
|
||||
|
||||
/*
|
||||
* Maximum length of the pi_provider_description field of the
|
||||
* crypto_provider_info structure.
|
||||
*/
|
||||
#define CRYPTO_PROVIDER_DESCR_MAX_LEN 64
|
||||
|
||||
|
||||
/* Bit mask for all the simple operations */
|
||||
#define CRYPTO_FG_SIMPLEOP_MASK (CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | \
|
||||
CRYPTO_FG_DIGEST | CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | CRYPTO_FG_MAC | \
|
||||
CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_DECRYPT_ATOMIC | \
|
||||
CRYPTO_FG_MAC_ATOMIC | CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_SIGN_ATOMIC | \
|
||||
CRYPTO_FG_VERIFY_ATOMIC)
|
||||
|
||||
/* Bit mask for all the dual operations */
|
||||
#define CRYPTO_FG_MAC_CIPHER_MASK (CRYPTO_FG_ENCRYPT_MAC | \
|
||||
CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | \
|
||||
CRYPTO_FG_MAC_DECRYPT_ATOMIC)
|
||||
|
||||
/* Add other combos to CRYPTO_FG_DUAL_MASK */
|
||||
#define CRYPTO_FG_DUAL_MASK CRYPTO_FG_MAC_CIPHER_MASK
|
||||
|
||||
/*
|
||||
* The crypto_mech_info structure specifies one of the mechanisms
|
||||
* supported by a cryptographic provider. The pi_mechanisms field of
|
||||
* the crypto_provider_info structure contains a pointer to an array
|
||||
* of crypto_mech_info's.
|
||||
*/
|
||||
typedef struct crypto_mech_info {
|
||||
crypto_mech_name_t cm_mech_name;
|
||||
crypto_mech_type_t cm_mech_number;
|
||||
crypto_func_group_t cm_func_group_mask;
|
||||
ssize_t cm_min_key_length;
|
||||
ssize_t cm_max_key_length;
|
||||
uint32_t cm_mech_flags;
|
||||
} crypto_mech_info_t;
|
||||
|
||||
/* Alias the old name to the new name for compatibility. */
|
||||
#define cm_keysize_unit cm_mech_flags
|
||||
|
||||
/*
|
||||
* The following is used by a provider that sets
|
||||
* CRYPTO_HASH_NO_UPDATE. It needs to specify the maximum
|
||||
* input data size it can digest in this field.
|
||||
*/
|
||||
#define cm_max_input_length cm_max_key_length
|
||||
|
||||
/*
|
||||
* crypto_kcf_provider_handle_t is a handle allocated by the kernel.
|
||||
* It is returned after the provider registers with
|
||||
* crypto_register_provider(), and must be specified by the provider
|
||||
* when calling crypto_unregister_provider(), and
|
||||
* crypto_provider_notification().
|
||||
*/
|
||||
typedef uint_t crypto_kcf_provider_handle_t;
|
||||
|
||||
/*
|
||||
* Provider information. Passed as argument to crypto_register_provider(9F).
|
||||
* Describes the provider and its capabilities. Multiple providers can
|
||||
* register for the same device instance. In this case, the same
|
||||
* pi_provider_dev must be specified with a different pi_provider_handle.
|
||||
*/
|
||||
typedef struct crypto_provider_info_v1 {
|
||||
uint_t pi_interface_version;
|
||||
char *pi_provider_description;
|
||||
crypto_provider_type_t pi_provider_type;
|
||||
crypto_provider_handle_t pi_provider_handle;
|
||||
crypto_ops_t *pi_ops_vector;
|
||||
uint_t pi_mech_list_count;
|
||||
crypto_mech_info_t *pi_mechanisms;
|
||||
uint_t pi_logical_provider_count;
|
||||
crypto_kcf_provider_handle_t *pi_logical_providers;
|
||||
} crypto_provider_info_v1_t;
|
||||
|
||||
typedef struct crypto_provider_info_v2 {
|
||||
crypto_provider_info_v1_t v1_info;
|
||||
uint_t pi_flags;
|
||||
} crypto_provider_info_v2_t;
|
||||
|
||||
typedef struct crypto_provider_info {
|
||||
union {
|
||||
crypto_provider_info_v2_t piu_v2;
|
||||
crypto_provider_info_v1_t piu_v1;
|
||||
} piu;
|
||||
} crypto_provider_info_t;
|
||||
|
||||
#define pi_interface_version piu.piu_v1.pi_interface_version
|
||||
#define pi_provider_description piu.piu_v1.pi_provider_description
|
||||
#define pi_provider_type piu.piu_v1.pi_provider_type
|
||||
#define pi_provider_handle piu.piu_v1.pi_provider_handle
|
||||
#define pi_ops_vector piu.piu_v1.pi_ops_vector
|
||||
#define pi_mech_list_count piu.piu_v1.pi_mech_list_count
|
||||
#define pi_mechanisms piu.piu_v1.pi_mechanisms
|
||||
#define pi_logical_provider_count piu.piu_v1.pi_logical_provider_count
|
||||
#define pi_logical_providers piu.piu_v1.pi_logical_providers
|
||||
#define pi_flags piu.piu_v2.pi_flags
|
||||
|
||||
/* hidden providers can only be accessed via a logical provider */
|
||||
#define CRYPTO_HIDE_PROVIDER 0x00000001
|
||||
/*
|
||||
* provider can not do multi-part digest (updates) and has a limit
|
||||
* on maximum input data that it can digest.
|
||||
*/
|
||||
#define CRYPTO_HASH_NO_UPDATE 0x00000002
|
||||
|
||||
/* provider can handle the request without returning a CRYPTO_QUEUED */
|
||||
#define CRYPTO_SYNCHRONOUS 0x00000004
|
||||
|
||||
#define CRYPTO_PIFLAGS_RESERVED2 0x40000000
|
||||
#define CRYPTO_PIFLAGS_RESERVED1 0x80000000
|
||||
|
||||
/*
|
||||
* Provider status passed by a provider to crypto_provider_notification(9F)
|
||||
* and returned by the provider_stauts(9E) entry point.
|
||||
*/
|
||||
#define CRYPTO_PROVIDER_READY 0
|
||||
#define CRYPTO_PROVIDER_BUSY 1
|
||||
#define CRYPTO_PROVIDER_FAILED 2
|
||||
|
||||
/*
|
||||
* Functions exported by Solaris to cryptographic providers. Providers
|
||||
* call these functions to register and unregister, notify the kernel
|
||||
* of state changes, and notify the kernel when a asynchronous request
|
||||
* completed.
|
||||
*/
|
||||
extern int crypto_register_provider(crypto_provider_info_t *,
|
||||
crypto_kcf_provider_handle_t *);
|
||||
extern int crypto_unregister_provider(crypto_kcf_provider_handle_t);
|
||||
extern void crypto_provider_notification(crypto_kcf_provider_handle_t, uint_t);
|
||||
extern void crypto_op_notification(crypto_req_handle_t, int);
|
||||
extern int crypto_kmflag(crypto_req_handle_t);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_CRYPTO_SPI_H */
|
||||
Reference in New Issue
Block a user