/* * Returns the provider descriptor corresponding to the specified * device name and instance. A REFHOLD is done on the descriptor * before it is returned to the caller. It is the responsibility * of the caller to do a REFRELE once it is done with the provider * descriptor. Only hardware providers are returned by this function. */ kcf_provider_desc_t * kcf_prov_tab_lookup_by_dev(char *name, uint_t instance) { kcf_provider_desc_t *prov_desc; uint_t i; mutex_enter(&prov_tab_mutex); for (i = 0; i < KCF_MAX_PROVIDERS; i++) { if ((prov_desc = prov_tab[i]) != NULL && (!KCF_IS_PROV_REMOVED(prov_desc)) && prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) { ASSERT(prov_desc->pd_name != NULL); if (strncmp(prov_desc->pd_name, name, MAXNAMELEN) == 0 && prov_desc->pd_instance == instance) { KCF_PROV_REFHOLD(prov_desc); mutex_exit(&prov_tab_mutex); return (prov_desc); } } } mutex_exit(&prov_tab_mutex); return (NULL); }
/* * We're done with this framework context, so free it. Note that freeing * framework context (kcf_context) frees the global context (crypto_ctx). * * The provider is responsible for freeing provider private context after a * final or single operation and resetting the cc_provider_private field * to NULL. It should do this before it notifies the framework of the * completion. We still need to call KCF_PROV_FREE_CONTEXT to handle cases * like crypto_cancel_ctx(9f). */ void kcf_free_context(kcf_context_t *kcf_ctx) { kcf_provider_desc_t *pd = kcf_ctx->kc_prov_desc; crypto_ctx_t *gctx = &kcf_ctx->kc_glbl_ctx; kcf_context_t *kcf_secondctx = kcf_ctx->kc_secondctx; /* Release the second context, if any */ if (kcf_secondctx != NULL) KCF_CONTEXT_REFRELE(kcf_secondctx); if (gctx->cc_provider_private != NULL) { mutex_enter(&pd->pd_lock); if (!KCF_IS_PROV_REMOVED(pd)) { /* * Increment the provider's internal refcnt so it * doesn't unregister from the framework while * we're calling the entry point. */ KCF_PROV_IREFHOLD(pd); mutex_exit(&pd->pd_lock); (void) KCF_PROV_FREE_CONTEXT(pd, gctx); KCF_PROV_IREFRELE(pd); } else { mutex_exit(&pd->pd_lock); } } /* kcf_ctx->kc_prov_desc has a hold on pd */ KCF_PROV_REFRELE(kcf_ctx->kc_prov_desc); /* check if this context is shared with a software provider */ if ((gctx->cc_flags & CRYPTO_INIT_OPSTATE) && kcf_ctx->kc_sw_prov_desc != NULL) { KCF_PROV_REFRELE(kcf_ctx->kc_sw_prov_desc); } kmem_cache_free(kcf_context_cache, kcf_ctx); }