1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or https://opensource.org/licenses/CDDL-1.0. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_CRYPTO_SCHED_IMPL_H 27 #define _SYS_CRYPTO_SCHED_IMPL_H 28 29 /* 30 * Scheduler internal structures. 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #include <sys/zfs_context.h> 38 #include <sys/crypto/api.h> 39 #include <sys/crypto/spi.h> 40 #include <sys/crypto/impl.h> 41 #include <sys/crypto/common.h> 42 43 typedef struct kcf_prov_tried { 44 kcf_provider_desc_t *pt_pd; 45 struct kcf_prov_tried *pt_next; 46 } kcf_prov_tried_t; 47 48 #define IS_FG_SUPPORTED(mdesc, fg) \ 49 (((mdesc)->pm_mech_info.cm_func_group_mask & (fg)) != 0) 50 51 #define IS_PROVIDER_TRIED(pd, tlist) \ 52 (tlist != NULL && is_in_triedlist(pd, tlist)) 53 54 #define IS_RECOVERABLE(error) \ 55 (error == CRYPTO_BUSY || \ 56 error == CRYPTO_KEY_SIZE_RANGE) 57 58 /* 59 * Internal representation of a canonical context. We contain crypto_ctx_t 60 * structure in order to have just one memory allocation. The SPI 61 * ((crypto_ctx_t *)ctx)->cc_framework_private maps to this structure. 62 */ 63 typedef struct kcf_context { 64 crypto_ctx_t kc_glbl_ctx; 65 uint_t kc_refcnt; 66 kcf_provider_desc_t *kc_prov_desc; /* Prov. descriptor */ 67 kcf_provider_desc_t *kc_sw_prov_desc; /* Prov. descriptor */ 68 } kcf_context_t; 69 70 /* 71 * Decrement the reference count on the framework private context. 72 * When the last reference is released, the framework private 73 * context structure is freed along with the global context. 74 */ 75 #define KCF_CONTEXT_REFRELE(ictx) { \ 76 membar_producer(); \ 77 int newval = atomic_add_32_nv(&(ictx)->kc_refcnt, -1); \ 78 ASSERT(newval != -1); \ 79 if (newval == 0) \ 80 kcf_free_context(ictx); \ 81 } 82 83 /* 84 * Check if we can release the context now. In case of CRYPTO_BUSY, 85 * the client can retry the request using the context, 86 * so we do not release the context. 87 * 88 * This macro should be called only from the final routine in 89 * an init/update/final sequence. We do not release the context in case 90 * of update operations. We require the consumer to free it 91 * explicitly, in case it wants to abandon the operation. This is done 92 * as there may be mechanisms in ECB mode that can continue even if 93 * an operation on a block fails. 94 */ 95 #define KCF_CONTEXT_COND_RELEASE(rv, kcf_ctx) { \ 96 if (KCF_CONTEXT_DONE(rv)) \ 97 KCF_CONTEXT_REFRELE(kcf_ctx); \ 98 } 99 100 /* 101 * This macro determines whether we're done with a context. 102 */ 103 #define KCF_CONTEXT_DONE(rv) \ 104 ((rv) != CRYPTO_BUSY && (rv) != CRYPTO_BUFFER_TOO_SMALL) 105 106 107 #define KCF_SET_PROVIDER_MECHNUM(fmtype, pd, mechp) \ 108 (mechp)->cm_type = \ 109 KCF_TO_PROV_MECHNUM(pd, fmtype); 110 111 /* 112 * A crypto_ctx_template_t is internally a pointer to this struct 113 */ 114 typedef struct kcf_ctx_template { 115 size_t ct_size; /* for freeing */ 116 crypto_spi_ctx_template_t ct_prov_tmpl; /* context template */ 117 /* from the provider */ 118 } kcf_ctx_template_t; 119 120 121 extern void kcf_free_triedlist(kcf_prov_tried_t *); 122 extern kcf_prov_tried_t *kcf_insert_triedlist(kcf_prov_tried_t **, 123 kcf_provider_desc_t *, int); 124 extern kcf_provider_desc_t *kcf_get_mech_provider(crypto_mech_type_t, 125 kcf_mech_entry_t **, int *, kcf_prov_tried_t *, crypto_func_group_t); 126 extern crypto_ctx_t *kcf_new_ctx(kcf_provider_desc_t *); 127 extern void kcf_sched_destroy(void); 128 extern void kcf_sched_init(void); 129 extern void kcf_free_context(kcf_context_t *); 130 131 #ifdef __cplusplus 132 } 133 #endif 134 135 #endif /* _SYS_CRYPTO_SCHED_IMPL_H */ 136