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