xref: /onnv-gate/usr/src/uts/common/crypto/api/kcf_ctxops.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <sys/errno.h>
30*0Sstevel@tonic-gate #include <sys/types.h>
31*0Sstevel@tonic-gate #include <sys/systm.h>
32*0Sstevel@tonic-gate #include <sys/kmem.h>
33*0Sstevel@tonic-gate #include <sys/crypto/common.h>
34*0Sstevel@tonic-gate #include <sys/crypto/impl.h>
35*0Sstevel@tonic-gate #include <sys/crypto/api.h>
36*0Sstevel@tonic-gate #include <sys/crypto/spi.h>
37*0Sstevel@tonic-gate #include <sys/crypto/sched_impl.h>
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate /*
40*0Sstevel@tonic-gate  * Crypto contexts manipulation routines
41*0Sstevel@tonic-gate  */
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate /*
44*0Sstevel@tonic-gate  * crypto_create_ctx_template()
45*0Sstevel@tonic-gate  *
46*0Sstevel@tonic-gate  * Arguments:
47*0Sstevel@tonic-gate  *
48*0Sstevel@tonic-gate  *	mech:	crypto_mechanism_t pointer.
49*0Sstevel@tonic-gate  *		mech_type is a valid value previously returned by
50*0Sstevel@tonic-gate  *		crypto_mech2id();
51*0Sstevel@tonic-gate  *		When the mech's parameter is not NULL, its definition depends
52*0Sstevel@tonic-gate  *		on the standard definition of the mechanism.
53*0Sstevel@tonic-gate  *	key:	pointer to a crypto_key_t structure.
54*0Sstevel@tonic-gate  *	ptmpl:	a storage for the opaque crypto_ctx_template_t, allocated and
55*0Sstevel@tonic-gate  *		initialized by the software provider this routine is
56*0Sstevel@tonic-gate  *		dispatched to.
57*0Sstevel@tonic-gate  *	kmflag:	KM_SLEEP/KM_NOSLEEP mem. alloc. flag.
58*0Sstevel@tonic-gate  *
59*0Sstevel@tonic-gate  * Description:
60*0Sstevel@tonic-gate  *	Redirects the call to the software provider of the specified
61*0Sstevel@tonic-gate  *	mechanism. That provider will allocate and pre-compute/pre-expand
62*0Sstevel@tonic-gate  *	the context template, reusable by later calls to crypto_xxx_init().
63*0Sstevel@tonic-gate  *	The size and address of that provider context template are stored
64*0Sstevel@tonic-gate  *	in an internal structure, kcf_ctx_template_t. The address of that
65*0Sstevel@tonic-gate  *	structure is given back to the caller in *ptmpl.
66*0Sstevel@tonic-gate  *
67*0Sstevel@tonic-gate  * Context:
68*0Sstevel@tonic-gate  *	Process or interrupt.
69*0Sstevel@tonic-gate  *
70*0Sstevel@tonic-gate  * Returns:
71*0Sstevel@tonic-gate  *	CRYPTO_SUCCESS when the context template is successfully created.
72*0Sstevel@tonic-gate  *	CRYPTO_HOST_MEMEORY: mem alloc failure
73*0Sstevel@tonic-gate  *	CRYPTO_ARGUMENTS_BAD: NULL storage for the ctx template.
74*0Sstevel@tonic-gate  *	RYPTO_MECHANISM_INVALID: invalid mechanism 'mech'.
75*0Sstevel@tonic-gate  */
76*0Sstevel@tonic-gate int
77*0Sstevel@tonic-gate crypto_create_ctx_template(crypto_mechanism_t *mech, crypto_key_t *key,
78*0Sstevel@tonic-gate     crypto_ctx_template_t *ptmpl, int kmflag)
79*0Sstevel@tonic-gate {
80*0Sstevel@tonic-gate 	int error;
81*0Sstevel@tonic-gate 	kcf_mech_entry_t *me;
82*0Sstevel@tonic-gate 	kcf_prov_mech_desc_t *pm;
83*0Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
84*0Sstevel@tonic-gate 	kcf_ctx_template_t *ctx_tmpl;
85*0Sstevel@tonic-gate 	crypto_mechanism_t prov_mech;
86*0Sstevel@tonic-gate 	kcf_ops_class_t class;
87*0Sstevel@tonic-gate 	int index;
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate 	/* A few args validation */
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate 	if (ptmpl == NULL)
92*0Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate 	if (mech == NULL)
95*0Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate 	if (kcf_get_mech_entry(mech->cm_type, &me) != KCF_SUCCESS) {
98*0Sstevel@tonic-gate 		/* error is one of the KCF_INVALID_MECH_XXX's */
99*0Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
100*0Sstevel@tonic-gate 	}
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	/*
103*0Sstevel@tonic-gate 	 * Get the software provider for the mech.
104*0Sstevel@tonic-gate 	 * Lock the mech_entry until we grab the 'pd'
105*0Sstevel@tonic-gate 	 */
106*0Sstevel@tonic-gate 	mutex_enter(&me->me_mutex);
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	if (((pm = me->me_sw_prov) == NULL) ||
109*0Sstevel@tonic-gate 	    ((pd = pm->pm_prov_desc) == NULL)) {
110*0Sstevel@tonic-gate 		mutex_exit(&me->me_mutex);
111*0Sstevel@tonic-gate 		return (CRYPTO_MECH_NOT_SUPPORTED);
112*0Sstevel@tonic-gate 	}
113*0Sstevel@tonic-gate 	KCF_PROV_REFHOLD(pd);
114*0Sstevel@tonic-gate 	mutex_exit(&me->me_mutex);
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 	if ((ctx_tmpl = (kcf_ctx_template_t *)kmem_alloc(
117*0Sstevel@tonic-gate 	    sizeof (kcf_ctx_template_t), kmflag)) == NULL) {
118*0Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
119*0Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
120*0Sstevel@tonic-gate 	}
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate 	/* Pass a mechtype that the provider understands */
123*0Sstevel@tonic-gate 	class = KCF_MECH2CLASS(mech->cm_type);
124*0Sstevel@tonic-gate 	index = KCF_MECH2INDEX(mech->cm_type);
125*0Sstevel@tonic-gate 	prov_mech.cm_type = pd->pd_map_mechnums[class][index];
126*0Sstevel@tonic-gate 	prov_mech.cm_param = mech->cm_param;
127*0Sstevel@tonic-gate 	prov_mech.cm_param_len = mech->cm_param_len;
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 	error = KCF_PROV_CREATE_CTX_TEMPLATE(pd, &prov_mech, key,
130*0Sstevel@tonic-gate 	    &(ctx_tmpl->ct_prov_tmpl), &(ctx_tmpl->ct_size), KCF_RHNDL(kmflag));
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 	if (error == CRYPTO_SUCCESS) {
133*0Sstevel@tonic-gate 		ctx_tmpl->ct_generation = me->me_gen_swprov;
134*0Sstevel@tonic-gate 		*ptmpl = ctx_tmpl;
135*0Sstevel@tonic-gate 	} else {
136*0Sstevel@tonic-gate 		kmem_free(ctx_tmpl, sizeof (kcf_ctx_template_t));
137*0Sstevel@tonic-gate 	}
138*0Sstevel@tonic-gate 	KCF_PROV_REFRELE(pd);
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	return (error);
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate /*
144*0Sstevel@tonic-gate  * crypto_destroy_ctx_template()
145*0Sstevel@tonic-gate  *
146*0Sstevel@tonic-gate  * Arguments:
147*0Sstevel@tonic-gate  *
148*0Sstevel@tonic-gate  *	tmpl:	an opaque crypto_ctx_template_t previously created by
149*0Sstevel@tonic-gate  *		crypto_create_ctx_template()
150*0Sstevel@tonic-gate  *
151*0Sstevel@tonic-gate  * Description:
152*0Sstevel@tonic-gate  *	Frees the inbedded crypto_spi_ctx_template_t, then the
153*0Sstevel@tonic-gate  *	kcf_ctx_template_t.
154*0Sstevel@tonic-gate  *
155*0Sstevel@tonic-gate  * Context:
156*0Sstevel@tonic-gate  *	Process or interrupt.
157*0Sstevel@tonic-gate  *
158*0Sstevel@tonic-gate  */
159*0Sstevel@tonic-gate void
160*0Sstevel@tonic-gate crypto_destroy_ctx_template(crypto_ctx_template_t tmpl)
161*0Sstevel@tonic-gate {
162*0Sstevel@tonic-gate 	kcf_ctx_template_t *ctx_tmpl = (kcf_ctx_template_t *)tmpl;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	if (ctx_tmpl == NULL)
165*0Sstevel@tonic-gate 		return;
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	ASSERT(ctx_tmpl->ct_prov_tmpl != NULL);
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	bzero(ctx_tmpl->ct_prov_tmpl, ctx_tmpl->ct_size);
170*0Sstevel@tonic-gate 	kmem_free(ctx_tmpl->ct_prov_tmpl, ctx_tmpl->ct_size);
171*0Sstevel@tonic-gate 	kmem_free(ctx_tmpl, sizeof (kcf_ctx_template_t));
172*0Sstevel@tonic-gate }
173