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 http://www.opensolaris.org/os/licensing.
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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/errno.h>
26 #include <sys/types.h>
27 #include <sys/kmem.h>
28 #include <sys/sysmacros.h>
29 #include <sys/crypto/common.h>
30 #include <sys/crypto/impl.h>
31 #include <sys/crypto/api.h>
32 #include <sys/crypto/spi.h>
33 #include <sys/crypto/sched_impl.h>
34
35 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f)
36 #define CRYPTO_CIPHER_MAC_OFFSET(f) offsetof(crypto_dual_cipher_mac_ops_t, f)
37
38 static int crypto_mac_decrypt_common(crypto_mechanism_t *,
39 crypto_mechanism_t *, crypto_dual_data_t *, crypto_key_t *, crypto_key_t *,
40 crypto_ctx_template_t, crypto_ctx_template_t, crypto_data_t *,
41 crypto_data_t *, crypto_call_req_t *, boolean_t);
42
43 static int crypto_mac_decrypt_common_prov(crypto_provider_t provider,
44 crypto_session_id_t sid, crypto_mechanism_t *, crypto_mechanism_t *,
45 crypto_dual_data_t *, crypto_key_t *, crypto_key_t *,
46 crypto_ctx_template_t, crypto_ctx_template_t, crypto_data_t *,
47 crypto_data_t *, crypto_call_req_t *, boolean_t);
48
49 int
crypto_encrypt_mac_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * encr_mech,crypto_mechanism_t * mac_mech,crypto_data_t * pt,crypto_key_t * encr_key,crypto_key_t * mac_key,crypto_ctx_template_t encr_tmpl,crypto_ctx_template_t mac_tmpl,crypto_dual_data_t * ct,crypto_data_t * mac,crypto_call_req_t * crq)50 crypto_encrypt_mac_prov(crypto_provider_t provider, crypto_session_id_t sid,
51 crypto_mechanism_t *encr_mech, crypto_mechanism_t *mac_mech,
52 crypto_data_t *pt, crypto_key_t *encr_key, crypto_key_t *mac_key,
53 crypto_ctx_template_t encr_tmpl, crypto_ctx_template_t mac_tmpl,
54 crypto_dual_data_t *ct, crypto_data_t *mac, crypto_call_req_t *crq)
55 {
56 /*
57 * First try to find a provider for the encryption mechanism, that
58 * is also capable of the MAC mechanism.
59 */
60 int rv;
61 kcf_mech_entry_t *me;
62 kcf_provider_desc_t *pd = provider;
63 kcf_provider_desc_t *real_provider = pd;
64 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl;
65 kcf_req_params_t params;
66 kcf_encrypt_mac_ops_params_t *cmops;
67 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL;
68
69 ASSERT(KCF_PROV_REFHELD(pd));
70
71 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
72 rv = kcf_get_hardware_provider(encr_mech->cm_type, encr_key,
73 mac_mech->cm_type, mac_key, pd, &real_provider,
74 CRYPTO_FG_ENCRYPT_MAC_ATOMIC);
75
76 if (rv != CRYPTO_SUCCESS)
77 return (rv);
78 }
79
80 /*
81 * For SW providers, check the validity of the context template
82 * It is very rare that the generation number mis-matches, so
83 * is acceptable to fail here, and let the consumer recover by
84 * freeing this tmpl and create a new one for the key and new SW
85 * provider
86 * Warning! will need to change when multiple software providers
87 * per mechanism are supported.
88 */
89
90 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) {
91 if (encr_tmpl != NULL) {
92 if (kcf_get_mech_entry(encr_mech->cm_type, &me) !=
93 KCF_SUCCESS) {
94 rv = CRYPTO_MECHANISM_INVALID;
95 goto out;
96 }
97 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl;
98 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) {
99 rv = CRYPTO_OLD_CTX_TEMPLATE;
100 goto out;
101 }
102 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl;
103 }
104
105 if (mac_tmpl != NULL) {
106 if (kcf_get_mech_entry(mac_mech->cm_type, &me) !=
107 KCF_SUCCESS) {
108 rv = CRYPTO_MECHANISM_INVALID;
109 goto out;
110 }
111 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
112 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
113 rv = CRYPTO_OLD_CTX_TEMPLATE;
114 goto out;
115 }
116 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
117 }
118 }
119
120 /* The fast path for SW providers. */
121 if (CHECK_FASTPATH(crq, real_provider)) {
122 crypto_mechanism_t lencr_mech;
123 crypto_mechanism_t lmac_mech;
124
125 /* careful! structs assignments */
126 lencr_mech = *encr_mech;
127 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider,
128 &lencr_mech);
129
130 lmac_mech = *mac_mech;
131 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
132 &lmac_mech);
133
134 rv = KCF_PROV_ENCRYPT_MAC_ATOMIC(real_provider, sid,
135 &lencr_mech, encr_key, &lmac_mech, mac_key, pt, ct,
136 mac, spi_encr_tmpl, spi_mac_tmpl, KCF_SWFP_RHNDL(crq));
137
138 KCF_PROV_INCRSTATS(pd, rv);
139 } else {
140 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_ATOMIC,
141 sid, encr_key, mac_key, pt, ct, mac, spi_encr_tmpl,
142 spi_mac_tmpl);
143
144 cmops = &(params.rp_u.encrypt_mac_params);
145
146 /* careful! structs assignments */
147 cmops->em_encr_mech = *encr_mech;
148 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider,
149 &cmops->em_encr_mech);
150 cmops->em_framework_encr_mechtype = encr_mech->cm_type;
151
152 cmops->em_mac_mech = *mac_mech;
153 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
154 &cmops->em_mac_mech);
155 cmops->em_framework_mac_mechtype = mac_mech->cm_type;
156
157 rv = kcf_submit_request(real_provider, NULL, crq, ¶ms,
158 B_FALSE);
159 }
160
161 out:
162 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
163 KCF_PROV_REFRELE(real_provider);
164 return (rv);
165 }
166
167 /*
168 * Performs a dual encrypt/mac atomic operation. The provider and session
169 * to use are determined by the KCF dispatcher.
170 */
171 int
crypto_encrypt_mac(crypto_mechanism_t * encr_mech,crypto_mechanism_t * mac_mech,crypto_data_t * pt,crypto_key_t * encr_key,crypto_key_t * mac_key,crypto_ctx_template_t encr_tmpl,crypto_ctx_template_t mac_tmpl,crypto_dual_data_t * ct,crypto_data_t * mac,crypto_call_req_t * crq)172 crypto_encrypt_mac(crypto_mechanism_t *encr_mech,
173 crypto_mechanism_t *mac_mech, crypto_data_t *pt,
174 crypto_key_t *encr_key, crypto_key_t *mac_key,
175 crypto_ctx_template_t encr_tmpl, crypto_ctx_template_t mac_tmpl,
176 crypto_dual_data_t *ct, crypto_data_t *mac, crypto_call_req_t *crq)
177 {
178 /*
179 * First try to find a provider for the encryption mechanism, that
180 * is also capable of the MAC mechanism.
181 */
182 int error;
183 kcf_mech_entry_t *me;
184 kcf_provider_desc_t *pd;
185 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl;
186 kcf_req_params_t params;
187 kcf_encrypt_mac_ops_params_t *cmops;
188 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL;
189 crypto_mech_type_t prov_encr_mechid, prov_mac_mechid;
190 kcf_prov_tried_t *list = NULL;
191 boolean_t encr_tmpl_checked = B_FALSE;
192 boolean_t mac_tmpl_checked = B_FALSE;
193 kcf_dual_req_t *next_req = NULL;
194
195 retry:
196 /* pd is returned held on success */
197 pd = kcf_get_dual_provider(encr_mech, encr_key, mac_mech, mac_key,
198 &me, &prov_encr_mechid,
199 &prov_mac_mechid, &error, list,
200 CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC,
201 CRYPTO_FG_MAC_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC,
202 ct->dd_len1);
203 if (pd == NULL) {
204 if (list != NULL)
205 kcf_free_triedlist(list);
206 if (next_req != NULL)
207 kmem_free(next_req, sizeof (kcf_dual_req_t));
208 return (error);
209 }
210
211 /*
212 * For SW providers, check the validity of the context template
213 * It is very rare that the generation number mis-matches, so
214 * is acceptable to fail here, and let the consumer recover by
215 * freeing this tmpl and create a new one for the key and new SW
216 * provider
217 * Warning! will need to change when multiple software providers
218 * per mechanism are supported.
219 */
220
221 if ((!encr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
222 if (encr_tmpl != NULL) {
223 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl;
224 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) {
225
226 if (next_req != NULL)
227 kmem_free(next_req,
228 sizeof (kcf_dual_req_t));
229 if (list != NULL)
230 kcf_free_triedlist(list);
231
232 KCF_PROV_REFRELE(pd);
233 /* Which one is the the old one ? */
234 return (CRYPTO_OLD_CTX_TEMPLATE);
235 }
236 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl;
237 }
238 encr_tmpl_checked = B_TRUE;
239 }
240
241 if (prov_mac_mechid == CRYPTO_MECH_INVALID) {
242 crypto_call_req_t encr_req;
243
244 /* Need to emulate with 2 internal calls */
245 /* Allocate and initialize the MAC req for the callback */
246
247 if (crq != NULL) {
248 if (next_req == NULL) {
249 next_req = kcf_alloc_req(crq);
250
251 if (next_req == NULL) {
252 KCF_PROV_REFRELE(pd);
253 if (list != NULL)
254 kcf_free_triedlist(list);
255 return (CRYPTO_HOST_MEMORY);
256 }
257 /*
258 * Careful! we're wrapping-in mac_tmpl instead
259 * of an spi_mac_tmpl. The callback routine will
260 * have to validate mac_tmpl, and use the
261 * mac_ctx_tmpl, once it picks a MAC provider.
262 */
263 KCF_WRAP_MAC_OPS_PARAMS(&(next_req->kr_params),
264 KCF_OP_ATOMIC, NULL, mac_mech, mac_key,
265 (crypto_data_t *)ct, mac, mac_tmpl);
266 }
267
268 encr_req.cr_flag = crq->cr_flag;
269 encr_req.cr_callback_func = kcf_next_req;
270 encr_req.cr_callback_arg = next_req;
271 }
272
273 if (pt == NULL) {
274 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC,
275 pd->pd_sid, encr_mech, encr_key,
276 (crypto_data_t *)ct, NULL, spi_encr_tmpl);
277 } else {
278 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC,
279 pd->pd_sid, encr_mech, encr_key, pt,
280 (crypto_data_t *)ct, spi_encr_tmpl);
281 }
282
283 error = kcf_submit_request(pd, NULL, (crq == NULL) ? NULL :
284 &encr_req, ¶ms, B_TRUE);
285
286 switch (error) {
287 case CRYPTO_SUCCESS: {
288 off_t saveoffset;
289 size_t savelen;
290
291 /*
292 * The encryption step is done. Reuse the encr_req
293 * for submitting the MAC step.
294 */
295 if (next_req == NULL) {
296 saveoffset = ct->dd_offset1;
297 savelen = ct->dd_len1;
298 } else {
299 saveoffset = next_req->kr_saveoffset =
300 ct->dd_offset1;
301 savelen = next_req->kr_savelen = ct->dd_len1;
302 encr_req.cr_callback_func = kcf_last_req;
303 }
304
305 ct->dd_offset1 = ct->dd_offset2;
306 ct->dd_len1 = ct->dd_len2;
307
308 error = crypto_mac(mac_mech, (crypto_data_t *)ct,
309 mac_key, mac_tmpl, mac, (crq == NULL) ? NULL :
310 &encr_req);
311
312 if (error != CRYPTO_QUEUED) {
313 ct->dd_offset1 = saveoffset;
314 ct->dd_len1 = savelen;
315 }
316 break;
317 }
318
319 case CRYPTO_QUEUED:
320 if ((crq != NULL) &&
321 !(crq->cr_flag & CRYPTO_SKIP_REQID))
322 crq->cr_reqid = encr_req.cr_reqid;
323 break;
324
325 default:
326
327 /* Add pd to the linked list of providers tried. */
328 if (IS_RECOVERABLE(error)) {
329 if (kcf_insert_triedlist(&list, pd,
330 KCF_KMFLAG(crq)) != NULL)
331 goto retry;
332 }
333 }
334 if (error != CRYPTO_QUEUED && next_req != NULL)
335 kmem_free(next_req, sizeof (kcf_dual_req_t));
336 if (list != NULL)
337 kcf_free_triedlist(list);
338 KCF_PROV_REFRELE(pd);
339 return (error);
340 }
341 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
342 if ((mac_tmpl != NULL) &&
343 (prov_mac_mechid != CRYPTO_MECH_INVALID)) {
344 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
345 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
346
347 if (next_req != NULL)
348 kmem_free(next_req,
349 sizeof (kcf_dual_req_t));
350 if (list != NULL)
351 kcf_free_triedlist(list);
352
353 KCF_PROV_REFRELE(pd);
354 /* Which one is the the old one ? */
355 return (CRYPTO_OLD_CTX_TEMPLATE);
356 }
357 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
358 }
359 mac_tmpl_checked = B_TRUE;
360 }
361
362 /* The fast path for SW providers. */
363 if (CHECK_FASTPATH(crq, pd)) {
364 crypto_mechanism_t lencr_mech;
365 crypto_mechanism_t lmac_mech;
366
367 /* careful! structs assignments */
368 lencr_mech = *encr_mech;
369 lencr_mech.cm_type = prov_encr_mechid;
370 lmac_mech = *mac_mech;
371 lmac_mech.cm_type = prov_mac_mechid;
372
373 error = KCF_PROV_ENCRYPT_MAC_ATOMIC(pd, pd->pd_sid,
374 &lencr_mech, encr_key, &lmac_mech, mac_key, pt, ct,
375 mac, spi_encr_tmpl, spi_mac_tmpl, KCF_SWFP_RHNDL(crq));
376
377 KCF_PROV_INCRSTATS(pd, error);
378 } else {
379 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_ATOMIC,
380 pd->pd_sid, encr_key, mac_key, pt, ct, mac, spi_encr_tmpl,
381 spi_mac_tmpl);
382
383 cmops = &(params.rp_u.encrypt_mac_params);
384
385 /* careful! structs assignments */
386 cmops->em_encr_mech = *encr_mech;
387 cmops->em_encr_mech.cm_type = prov_encr_mechid;
388 cmops->em_framework_encr_mechtype = encr_mech->cm_type;
389 cmops->em_mac_mech = *mac_mech;
390 cmops->em_mac_mech.cm_type = prov_mac_mechid;
391 cmops->em_framework_mac_mechtype = mac_mech->cm_type;
392
393 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE);
394 }
395
396 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
397 IS_RECOVERABLE(error)) {
398 /* Add pd to the linked list of providers tried. */
399 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
400 goto retry;
401 }
402
403 if (next_req != NULL)
404 kmem_free(next_req, sizeof (kcf_dual_req_t));
405
406 if (list != NULL)
407 kcf_free_triedlist(list);
408
409 KCF_PROV_REFRELE(pd);
410 return (error);
411 }
412
413 int
crypto_encrypt_mac_init_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * encr_mech,crypto_mechanism_t * mac_mech,crypto_key_t * encr_key,crypto_key_t * mac_key,crypto_ctx_template_t encr_tmpl,crypto_ctx_template_t mac_tmpl,crypto_context_t * ctxp,crypto_call_req_t * cr)414 crypto_encrypt_mac_init_prov(crypto_provider_t provider,
415 crypto_session_id_t sid, crypto_mechanism_t *encr_mech,
416 crypto_mechanism_t *mac_mech, crypto_key_t *encr_key,
417 crypto_key_t *mac_key, crypto_ctx_template_t encr_tmpl,
418 crypto_ctx_template_t mac_tmpl, crypto_context_t *ctxp,
419 crypto_call_req_t *cr)
420 {
421 /*
422 * First try to find a provider for the encryption mechanism, that
423 * is also capable of the MAC mechanism.
424 */
425 int rv;
426 kcf_mech_entry_t *me;
427 kcf_provider_desc_t *pd = provider;
428 kcf_provider_desc_t *real_provider = pd;
429 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl;
430 kcf_req_params_t params;
431 kcf_encrypt_mac_ops_params_t *cmops;
432 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL;
433 crypto_ctx_t *ctx;
434 kcf_context_t *encr_kcf_context = NULL;
435
436 ASSERT(KCF_PROV_REFHELD(pd));
437
438 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
439 rv = kcf_get_hardware_provider(encr_mech->cm_type, encr_key,
440 mac_mech->cm_type, mac_key, pd, &real_provider,
441 CRYPTO_FG_ENCRYPT_MAC);
442
443 if (rv != CRYPTO_SUCCESS)
444 return (rv);
445 }
446
447 /*
448 * For SW providers, check the validity of the context template
449 * It is very rare that the generation number mis-matches, so
450 * is acceptable to fail here, and let the consumer recover by
451 * freeing this tmpl and create a new one for the key and new SW
452 * provider
453 * Warning! will need to change when multiple software providers
454 * per mechanism are supported.
455 */
456
457 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) {
458 if (encr_tmpl != NULL) {
459 if (kcf_get_mech_entry(encr_mech->cm_type, &me) !=
460 KCF_SUCCESS) {
461 rv = CRYPTO_MECHANISM_INVALID;
462 goto out;
463 }
464 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl;
465 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) {
466 rv = CRYPTO_OLD_CTX_TEMPLATE;
467 goto out;
468 }
469 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl;
470 }
471
472 if (mac_tmpl != NULL) {
473 if (kcf_get_mech_entry(mac_mech->cm_type, &me) !=
474 KCF_SUCCESS) {
475 rv = CRYPTO_MECHANISM_INVALID;
476 goto out;
477 }
478 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
479 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
480 rv = CRYPTO_OLD_CTX_TEMPLATE;
481 goto out;
482 }
483 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
484 }
485 }
486
487 ctx = kcf_new_ctx(cr, real_provider, sid);
488 if (ctx == NULL) {
489 rv = CRYPTO_HOST_MEMORY;
490 goto out;
491 }
492 encr_kcf_context = (kcf_context_t *)ctx->cc_framework_private;
493
494 /* The fast path for SW providers. */
495 if (CHECK_FASTPATH(cr, real_provider)) {
496 crypto_mechanism_t lencr_mech;
497 crypto_mechanism_t lmac_mech;
498
499 /* careful! structs assignments */
500 lencr_mech = *encr_mech;
501 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider,
502 &lencr_mech);
503
504 lmac_mech = *mac_mech;
505 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
506 &lmac_mech);
507
508 rv = KCF_PROV_ENCRYPT_MAC_INIT(real_provider, ctx, &lencr_mech,
509 encr_key, &lmac_mech, mac_key, spi_encr_tmpl, spi_mac_tmpl,
510 KCF_SWFP_RHNDL(cr));
511
512 KCF_PROV_INCRSTATS(pd, rv);
513 } else {
514 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_INIT,
515 sid, encr_key, mac_key, NULL, NULL, NULL,
516 spi_encr_tmpl, spi_mac_tmpl);
517
518 cmops = &(params.rp_u.encrypt_mac_params);
519
520 /* careful! structs assignments */
521 cmops->em_encr_mech = *encr_mech;
522 KCF_SET_PROVIDER_MECHNUM(encr_mech->cm_type, real_provider,
523 &cmops->em_encr_mech);
524 cmops->em_framework_encr_mechtype = encr_mech->cm_type;
525
526 cmops->em_mac_mech = *mac_mech;
527 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
528 &cmops->em_mac_mech);
529 cmops->em_framework_mac_mechtype = mac_mech->cm_type;
530
531 rv = kcf_submit_request(real_provider, ctx, cr, ¶ms,
532 B_FALSE);
533 }
534
535 if (rv != CRYPTO_SUCCESS && rv != CRYPTO_QUEUED) {
536 KCF_CONTEXT_REFRELE(encr_kcf_context);
537 } else
538 *ctxp = (crypto_context_t)ctx;
539
540 out:
541 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
542 KCF_PROV_REFRELE(real_provider);
543 return (rv);
544 }
545
546 /*
547 * Starts a multi-part dual encrypt/mac operation. The provider and session
548 * to use are determined by the KCF dispatcher.
549 */
550 /* ARGSUSED */
551 int
crypto_encrypt_mac_init(crypto_mechanism_t * encr_mech,crypto_mechanism_t * mac_mech,crypto_key_t * encr_key,crypto_key_t * mac_key,crypto_ctx_template_t encr_tmpl,crypto_ctx_template_t mac_tmpl,crypto_context_t * ctxp,crypto_call_req_t * cr)552 crypto_encrypt_mac_init(crypto_mechanism_t *encr_mech,
553 crypto_mechanism_t *mac_mech, crypto_key_t *encr_key,
554 crypto_key_t *mac_key, crypto_ctx_template_t encr_tmpl,
555 crypto_ctx_template_t mac_tmpl, crypto_context_t *ctxp,
556 crypto_call_req_t *cr)
557 {
558 /*
559 * First try to find a provider for the encryption mechanism, that
560 * is also capable of the MAC mechanism.
561 */
562 int error;
563 kcf_mech_entry_t *me;
564 kcf_provider_desc_t *pd;
565 kcf_ctx_template_t *ctx_encr_tmpl, *ctx_mac_tmpl;
566 kcf_req_params_t params;
567 kcf_encrypt_mac_ops_params_t *cmops;
568 crypto_spi_ctx_template_t spi_encr_tmpl = NULL, spi_mac_tmpl = NULL;
569 crypto_mech_type_t prov_encr_mechid, prov_mac_mechid;
570 kcf_prov_tried_t *list = NULL;
571 boolean_t encr_tmpl_checked = B_FALSE;
572 boolean_t mac_tmpl_checked = B_FALSE;
573 crypto_ctx_t *ctx = NULL;
574 kcf_context_t *encr_kcf_context = NULL, *mac_kcf_context;
575 crypto_call_flag_t save_flag;
576
577 retry:
578 /* pd is returned held on success */
579 pd = kcf_get_dual_provider(encr_mech, encr_key, mac_mech, mac_key,
580 &me, &prov_encr_mechid,
581 &prov_mac_mechid, &error, list,
582 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_MAC, CRYPTO_FG_MAC, 0);
583 if (pd == NULL) {
584 if (list != NULL)
585 kcf_free_triedlist(list);
586 return (error);
587 }
588
589 /*
590 * For SW providers, check the validity of the context template
591 * It is very rare that the generation number mis-matches, so
592 * is acceptable to fail here, and let the consumer recover by
593 * freeing this tmpl and create a new one for the key and new SW
594 * provider
595 * Warning! will need to change when multiple software providers
596 * per mechanism are supported.
597 */
598
599 if ((!encr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
600 if (encr_tmpl != NULL) {
601 ctx_encr_tmpl = (kcf_ctx_template_t *)encr_tmpl;
602 if (ctx_encr_tmpl->ct_generation != me->me_gen_swprov) {
603
604 if (list != NULL)
605 kcf_free_triedlist(list);
606 if (encr_kcf_context != NULL)
607 KCF_CONTEXT_REFRELE(encr_kcf_context);
608
609 KCF_PROV_REFRELE(pd);
610 /* Which one is the the old one ? */
611 return (CRYPTO_OLD_CTX_TEMPLATE);
612 }
613 spi_encr_tmpl = ctx_encr_tmpl->ct_prov_tmpl;
614 }
615 encr_tmpl_checked = B_TRUE;
616 }
617
618 if (prov_mac_mechid == CRYPTO_MECH_INVALID) {
619 /* Need to emulate with 2 internal calls */
620
621 /*
622 * We avoid code complexity by limiting the pure async.
623 * case to be done using only a SW provider.
624 * XXX - Redo the emulation code below so that we can
625 * remove this limitation.
626 */
627 if (cr != NULL && pd->pd_prov_type == CRYPTO_HW_PROVIDER) {
628 if ((kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr))
629 != NULL))
630 goto retry;
631 if (list != NULL)
632 kcf_free_triedlist(list);
633 if (encr_kcf_context != NULL)
634 KCF_CONTEXT_REFRELE(encr_kcf_context);
635 KCF_PROV_REFRELE(pd);
636 return (CRYPTO_HOST_MEMORY);
637 }
638
639 if (ctx == NULL && pd->pd_prov_type == CRYPTO_SW_PROVIDER) {
640 ctx = kcf_new_ctx(cr, pd, pd->pd_sid);
641 if (ctx == NULL) {
642 if (list != NULL)
643 kcf_free_triedlist(list);
644 if (encr_kcf_context != NULL)
645 KCF_CONTEXT_REFRELE(encr_kcf_context);
646 KCF_PROV_REFRELE(pd);
647 return (CRYPTO_HOST_MEMORY);
648 }
649 encr_kcf_context = (kcf_context_t *)
650 ctx->cc_framework_private;
651 }
652 /*
653 * Trade-off speed vs avoidance of code complexity and
654 * duplication:
655 * Could do all the combinations of fastpath / synch / asynch
656 * for the encryption and the mac steps. Early attempts
657 * showed the code grew wild and bug-prone, for little gain.
658 * Therefore, the adaptative asynch case is not implemented.
659 * It's either pure synchronous, or pure asynchronous.
660 * We still preserve a fastpath for the pure synchronous
661 * requests to SW providers.
662 */
663 if (cr == NULL) {
664 crypto_context_t mac_context;
665
666 if (pd->pd_prov_type == CRYPTO_SW_PROVIDER) {
667 crypto_mechanism_t lmech = *encr_mech;
668
669 lmech.cm_type = prov_encr_mechid;
670
671 error = KCF_PROV_ENCRYPT_INIT(pd, ctx, &lmech,
672 encr_key, spi_encr_tmpl,
673 KCF_RHNDL(KM_SLEEP));
674 } else {
675 /*
676 * If we did the 'goto retry' then ctx may not
677 * be NULL. In general, we can't reuse another
678 * provider's context, so we free it now so
679 * we don't leak it.
680 */
681 if (ctx != NULL) {
682 KCF_CONTEXT_REFRELE((kcf_context_t *)
683 ctx->cc_framework_private);
684 encr_kcf_context = NULL;
685 }
686 error = crypto_encrypt_init_prov(pd, pd->pd_sid,
687 encr_mech, encr_key, &encr_tmpl,
688 (crypto_context_t *)&ctx, NULL);
689
690 if (error == CRYPTO_SUCCESS) {
691 encr_kcf_context = (kcf_context_t *)
692 ctx->cc_framework_private;
693 }
694 }
695 KCF_PROV_INCRSTATS(pd, error);
696
697 KCF_PROV_REFRELE(pd);
698
699 if (error != CRYPTO_SUCCESS) {
700 /* Can't be CRYPTO_QUEUED. return the failure */
701 if (list != NULL)
702 kcf_free_triedlist(list);
703 if (encr_kcf_context != NULL)
704 KCF_CONTEXT_REFRELE(encr_kcf_context);
705
706 return (error);
707 }
708 error = crypto_mac_init(mac_mech, mac_key, mac_tmpl,
709 &mac_context, NULL);
710
711 if (list != NULL)
712 kcf_free_triedlist(list);
713
714 if (error != CRYPTO_SUCCESS) {
715 /* Should this be an ASSERT() ? */
716
717 KCF_CONTEXT_REFRELE(encr_kcf_context);
718 } else {
719 encr_kcf_context = (kcf_context_t *)
720 ctx->cc_framework_private;
721 mac_kcf_context = (kcf_context_t *)
722 ((crypto_ctx_t *)mac_context)->
723 cc_framework_private;
724
725 encr_kcf_context->kc_secondctx =
726 mac_kcf_context;
727 KCF_CONTEXT_REFHOLD(mac_kcf_context);
728
729 *ctxp = (crypto_context_t)ctx;
730 }
731
732 return (error);
733 }
734
735 /* submit a pure asynchronous request. */
736 save_flag = cr->cr_flag;
737 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE;
738
739 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_INIT,
740 pd->pd_sid, encr_key, mac_key, NULL, NULL, NULL,
741 spi_encr_tmpl, spi_mac_tmpl);
742
743 cmops = &(params.rp_u.encrypt_mac_params);
744
745 /* careful! structs assignments */
746 cmops->em_encr_mech = *encr_mech;
747 /*
748 * cmops->em_encr_mech.cm_type will be set when we get to
749 * kcf_emulate_dual() routine.
750 */
751 cmops->em_framework_encr_mechtype = encr_mech->cm_type;
752 cmops->em_mac_mech = *mac_mech;
753
754 /*
755 * cmops->em_mac_mech.cm_type will be set when we know the
756 * MAC provider.
757 */
758 cmops->em_framework_mac_mechtype = mac_mech->cm_type;
759
760 /*
761 * non-NULL ctx->kc_secondctx tells common_submit_request
762 * that this request uses separate cipher and MAC contexts.
763 * That function will set ctx->kc_secondctx to the new
764 * MAC context, once it gets one.
765 */
766 encr_kcf_context->kc_secondctx = encr_kcf_context;
767
768 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
769
770 cr->cr_flag = save_flag;
771
772 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) {
773 KCF_CONTEXT_REFRELE(encr_kcf_context);
774 }
775 if (list != NULL)
776 kcf_free_triedlist(list);
777 *ctxp = (crypto_context_t)ctx;
778 KCF_PROV_REFRELE(pd);
779 return (error);
780 }
781
782 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
783 if ((mac_tmpl != NULL) &&
784 (prov_mac_mechid != CRYPTO_MECH_INVALID)) {
785 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
786 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
787
788 if (list != NULL)
789 kcf_free_triedlist(list);
790
791 KCF_PROV_REFRELE(pd);
792 /* Which one is the the old one ? */
793 return (CRYPTO_OLD_CTX_TEMPLATE);
794 }
795 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
796 }
797 mac_tmpl_checked = B_TRUE;
798 }
799
800 if (ctx == NULL) {
801 ctx = kcf_new_ctx(cr, pd, pd->pd_sid);
802 if (ctx == NULL) {
803 if (list != NULL)
804 kcf_free_triedlist(list);
805
806 KCF_PROV_REFRELE(pd);
807 return (CRYPTO_HOST_MEMORY);
808 }
809 encr_kcf_context = (kcf_context_t *)ctx->cc_framework_private;
810 }
811
812 /* The fast path for SW providers. */
813 if (CHECK_FASTPATH(cr, pd)) {
814 crypto_mechanism_t lencr_mech;
815 crypto_mechanism_t lmac_mech;
816
817 /* careful! structs assignments */
818 lencr_mech = *encr_mech;
819 lencr_mech.cm_type = prov_encr_mechid;
820 lmac_mech = *mac_mech;
821 lmac_mech.cm_type = prov_mac_mechid;
822
823 error = KCF_PROV_ENCRYPT_MAC_INIT(pd, ctx, &lencr_mech,
824 encr_key, &lmac_mech, mac_key, spi_encr_tmpl, spi_mac_tmpl,
825 KCF_SWFP_RHNDL(cr));
826
827 KCF_PROV_INCRSTATS(pd, error);
828 } else {
829 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_INIT,
830 pd->pd_sid, encr_key, mac_key, NULL, NULL, NULL,
831 spi_encr_tmpl, spi_mac_tmpl);
832
833 cmops = &(params.rp_u.encrypt_mac_params);
834
835 /* careful! structs assignments */
836 cmops->em_encr_mech = *encr_mech;
837 cmops->em_encr_mech.cm_type = prov_encr_mechid;
838 cmops->em_framework_encr_mechtype = encr_mech->cm_type;
839 cmops->em_mac_mech = *mac_mech;
840 cmops->em_mac_mech.cm_type = prov_mac_mechid;
841 cmops->em_framework_mac_mechtype = mac_mech->cm_type;
842
843 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
844 }
845
846 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) {
847 if ((IS_RECOVERABLE(error)) &&
848 (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr)) != NULL))
849 goto retry;
850
851 KCF_CONTEXT_REFRELE(encr_kcf_context);
852 } else
853 *ctxp = (crypto_context_t)ctx;
854
855 if (list != NULL)
856 kcf_free_triedlist(list);
857
858 KCF_PROV_REFRELE(pd);
859 return (error);
860 }
861
862 /*
863 * Continues a multi-part dual encrypt/mac operation.
864 */
865 /* ARGSUSED */
866 int
crypto_encrypt_mac_update(crypto_context_t context,crypto_data_t * pt,crypto_dual_data_t * ct,crypto_call_req_t * cr)867 crypto_encrypt_mac_update(crypto_context_t context,
868 crypto_data_t *pt, crypto_dual_data_t *ct, crypto_call_req_t *cr)
869 {
870 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx;
871 kcf_context_t *kcf_ctx, *kcf_mac_ctx;
872 kcf_provider_desc_t *pd;
873 int error;
874 kcf_req_params_t params;
875
876 if ((ctx == NULL) ||
877 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
878 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
879 return (CRYPTO_INVALID_CONTEXT);
880 }
881
882 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
883
884 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) {
885 off_t save_offset;
886 size_t save_len;
887 crypto_call_flag_t save_flag;
888
889 if (kcf_mac_ctx->kc_prov_desc == NULL) {
890 error = CRYPTO_INVALID_CONTEXT;
891 goto out;
892 }
893 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx;
894
895 /* First we submit the encryption request */
896 if (cr == NULL) {
897 /*
898 * 'ct' is always not NULL.
899 * A NULL 'pt' means in-place.
900 */
901 if (pt == NULL)
902 error = crypto_encrypt_update(context,
903 (crypto_data_t *)ct, NULL, NULL);
904 else
905 error = crypto_encrypt_update(context, pt,
906 (crypto_data_t *)ct, NULL);
907
908 if (error != CRYPTO_SUCCESS)
909 goto out;
910
911 /*
912 * call mac_update when there is data to throw in
913 * the mix. Either an explicitly non-zero ct->dd_len2,
914 * or the last ciphertext portion.
915 */
916 save_offset = ct->dd_offset1;
917 save_len = ct->dd_len1;
918 if (ct->dd_len2 == 0) {
919 /*
920 * The previous encrypt step was an
921 * accumulation only and didn't produce any
922 * partial output
923 */
924 if (ct->dd_len1 == 0)
925 goto out;
926 } else {
927 ct->dd_offset1 = ct->dd_offset2;
928 ct->dd_len1 = ct->dd_len2;
929 }
930 error = crypto_mac_update((crypto_context_t)mac_ctx,
931 (crypto_data_t *)ct, NULL);
932
933 ct->dd_offset1 = save_offset;
934 ct->dd_len1 = save_len;
935
936 goto out;
937 }
938 /* submit a pure asynchronous request. */
939 save_flag = cr->cr_flag;
940 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE;
941
942 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_UPDATE,
943 pd->pd_sid, NULL, NULL, pt, ct, NULL, NULL, NULL)
944
945
946 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
947
948 cr->cr_flag = save_flag;
949 goto out;
950 }
951
952 /* The fast path for SW providers. */
953 if (CHECK_FASTPATH(cr, pd)) {
954 error = KCF_PROV_ENCRYPT_MAC_UPDATE(pd, ctx, pt, ct, NULL);
955 KCF_PROV_INCRSTATS(pd, error);
956 } else {
957 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_UPDATE,
958 ctx->cc_session, NULL, NULL, pt, ct, NULL, NULL, NULL);
959
960 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
961 }
962 out:
963 return (error);
964 }
965
966 /*
967 * Terminates a multi-part dual encrypt/mac operation.
968 */
969 /* ARGSUSED */
crypto_encrypt_mac_final(crypto_context_t context,crypto_dual_data_t * ct,crypto_data_t * mac,crypto_call_req_t * cr)970 int crypto_encrypt_mac_final(crypto_context_t context, crypto_dual_data_t *ct,
971 crypto_data_t *mac, crypto_call_req_t *cr)
972 {
973 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx;
974 kcf_context_t *kcf_ctx, *kcf_mac_ctx;
975 kcf_provider_desc_t *pd;
976 int error;
977 kcf_req_params_t params;
978
979 if ((ctx == NULL) ||
980 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
981 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
982 return (CRYPTO_INVALID_CONTEXT);
983 }
984
985 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
986
987 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) {
988 off_t save_offset;
989 size_t save_len;
990 crypto_context_t mac_context;
991 crypto_call_flag_t save_flag;
992
993 if (kcf_mac_ctx->kc_prov_desc == NULL) {
994 return (CRYPTO_INVALID_CONTEXT);
995 }
996 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx;
997 mac_context = (crypto_context_t)mac_ctx;
998
999 if (cr == NULL) {
1000 /* Get the last chunk of ciphertext */
1001 error = crypto_encrypt_final(context,
1002 (crypto_data_t *)ct, NULL);
1003
1004 if (error != CRYPTO_SUCCESS) {
1005 /*
1006 * Needed here, because the caller of
1007 * crypto_encrypt_mac_final() lost all
1008 * refs to the mac_ctx.
1009 */
1010 crypto_cancel_ctx(mac_context);
1011 return (error);
1012 }
1013 if (ct->dd_len2 > 0) {
1014 save_offset = ct->dd_offset1;
1015 save_len = ct->dd_len1;
1016 ct->dd_offset1 = ct->dd_offset2;
1017 ct->dd_len1 = ct->dd_len2;
1018
1019 error = crypto_mac_update(mac_context,
1020 (crypto_data_t *)ct, NULL);
1021
1022 ct->dd_offset1 = save_offset;
1023 ct->dd_len1 = save_len;
1024
1025 if (error != CRYPTO_SUCCESS) {
1026 crypto_cancel_ctx(mac_context);
1027 return (error);
1028 }
1029 }
1030
1031 /* and finally, collect the MAC */
1032 error = crypto_mac_final(mac_context, mac, NULL);
1033
1034 return (error);
1035 }
1036 /* submit a pure asynchronous request. */
1037 save_flag = cr->cr_flag;
1038 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE;
1039
1040 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_FINAL,
1041 pd->pd_sid, NULL, NULL, NULL, ct, mac, NULL, NULL)
1042
1043
1044 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
1045
1046 cr->cr_flag = save_flag;
1047 return (error);
1048 }
1049 /* The fast path for SW providers. */
1050 if (CHECK_FASTPATH(cr, pd)) {
1051 error = KCF_PROV_ENCRYPT_MAC_FINAL(pd, ctx, ct, mac, NULL);
1052 KCF_PROV_INCRSTATS(pd, error);
1053 } else {
1054 KCF_WRAP_ENCRYPT_MAC_OPS_PARAMS(¶ms, KCF_OP_FINAL,
1055 ctx->cc_session, NULL, NULL, NULL, ct, mac, NULL, NULL);
1056 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
1057 }
1058 out:
1059 /* Release the hold done in kcf_new_ctx() during init step. */
1060 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
1061 return (error);
1062 }
1063
1064 /*
1065 * Performs an atomic dual mac/decrypt operation. The provider to use
1066 * is determined by the KCF dispatcher.
1067 */
1068 int
crypto_mac_decrypt(crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_dual_data_t * ct,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_data_t * mac,crypto_data_t * pt,crypto_call_req_t * crq)1069 crypto_mac_decrypt(crypto_mechanism_t *mac_mech,
1070 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct,
1071 crypto_key_t *mac_key, crypto_key_t *decr_key,
1072 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl,
1073 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq)
1074 {
1075 return (crypto_mac_decrypt_common(mac_mech, decr_mech, ct, mac_key,
1076 decr_key, mac_tmpl, decr_tmpl, mac, pt, crq, B_FALSE));
1077 }
1078
1079 int
crypto_mac_decrypt_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_dual_data_t * ct,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_data_t * mac,crypto_data_t * pt,crypto_call_req_t * crq)1080 crypto_mac_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
1081 crypto_mechanism_t *mac_mech, crypto_mechanism_t *decr_mech,
1082 crypto_dual_data_t *ct, crypto_key_t *mac_key, crypto_key_t *decr_key,
1083 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl,
1084 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq)
1085 {
1086 return (crypto_mac_decrypt_common_prov(provider, sid, mac_mech,
1087 decr_mech, ct, mac_key, decr_key, mac_tmpl, decr_tmpl, mac, pt,
1088 crq, B_FALSE));
1089 }
1090
1091 /*
1092 * Performs an atomic dual mac/decrypt operation. The provider to use
1093 * is determined by the KCF dispatcher. 'mac' specifies the expected
1094 * value for the MAC. The decryption is not performed if the computed
1095 * MAC does not match the expected MAC.
1096 */
1097 int
crypto_mac_verify_decrypt(crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_dual_data_t * ct,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_data_t * mac,crypto_data_t * pt,crypto_call_req_t * crq)1098 crypto_mac_verify_decrypt(crypto_mechanism_t *mac_mech,
1099 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct,
1100 crypto_key_t *mac_key, crypto_key_t *decr_key,
1101 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl,
1102 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq)
1103 {
1104 return (crypto_mac_decrypt_common(mac_mech, decr_mech, ct, mac_key,
1105 decr_key, mac_tmpl, decr_tmpl, mac, pt, crq, B_TRUE));
1106 }
1107
1108 int
crypto_mac_verify_decrypt_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_dual_data_t * ct,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_data_t * mac,crypto_data_t * pt,crypto_call_req_t * crq)1109 crypto_mac_verify_decrypt_prov(crypto_provider_t provider,
1110 crypto_session_id_t sid, crypto_mechanism_t *mac_mech,
1111 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct,
1112 crypto_key_t *mac_key, crypto_key_t *decr_key,
1113 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl,
1114 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq)
1115 {
1116 return (crypto_mac_decrypt_common_prov(provider, sid, mac_mech,
1117 decr_mech, ct, mac_key, decr_key, mac_tmpl, decr_tmpl, mac, pt,
1118 crq, B_TRUE));
1119 }
1120
1121 /*
1122 * Called by both crypto_mac_decrypt() and crypto_mac_verify_decrypt().
1123 * optionally verified if the MACs match before calling the decryption step.
1124 */
1125 static int
crypto_mac_decrypt_common(crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_dual_data_t * ct,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_data_t * mac,crypto_data_t * pt,crypto_call_req_t * crq,boolean_t do_verify)1126 crypto_mac_decrypt_common(crypto_mechanism_t *mac_mech,
1127 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct,
1128 crypto_key_t *mac_key, crypto_key_t *decr_key,
1129 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl,
1130 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq,
1131 boolean_t do_verify)
1132 {
1133 /*
1134 * First try to find a provider for the decryption mechanism, that
1135 * is also capable of the MAC mechanism.
1136 * We still favor optimizing the costlier decryption.
1137 */
1138 int error;
1139 kcf_mech_entry_t *me;
1140 kcf_provider_desc_t *pd;
1141 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl;
1142 kcf_req_params_t params;
1143 kcf_mac_decrypt_ops_params_t *cmops;
1144 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL;
1145 crypto_mech_type_t prov_decr_mechid, prov_mac_mechid;
1146 kcf_prov_tried_t *list = NULL;
1147 boolean_t decr_tmpl_checked = B_FALSE;
1148 boolean_t mac_tmpl_checked = B_FALSE;
1149 kcf_dual_req_t *next_req = NULL;
1150 crypto_call_req_t mac_req, *mac_reqp = NULL;
1151
1152 retry:
1153 /* pd is returned held on success */
1154 pd = kcf_get_dual_provider(decr_mech, decr_key, mac_mech, mac_key,
1155 &me, &prov_decr_mechid,
1156 &prov_mac_mechid, &error, list,
1157 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
1158 CRYPTO_FG_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, ct->dd_len2);
1159 if (pd == NULL) {
1160 if (list != NULL)
1161 kcf_free_triedlist(list);
1162 if (next_req != NULL)
1163 kmem_free(next_req, sizeof (kcf_dual_req_t));
1164 return (CRYPTO_MECH_NOT_SUPPORTED);
1165 }
1166
1167 /*
1168 * For SW providers, check the validity of the context template
1169 * It is very rare that the generation number mis-matches, so
1170 * is acceptable to fail here, and let the consumer recover by
1171 * freeing this tmpl and create a new one for the key and new SW
1172 * provider
1173 */
1174
1175 if ((!decr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
1176 if (decr_tmpl != NULL) {
1177 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl;
1178 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) {
1179 if (next_req != NULL)
1180 kmem_free(next_req,
1181 sizeof (kcf_dual_req_t));
1182 if (list != NULL)
1183 kcf_free_triedlist(list);
1184 KCF_PROV_REFRELE(pd);
1185
1186 /* Which one is the the old one ? */
1187 return (CRYPTO_OLD_CTX_TEMPLATE);
1188 }
1189 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl;
1190 }
1191 decr_tmpl_checked = B_TRUE;
1192 }
1193 if (prov_mac_mechid == CRYPTO_MECH_INVALID) {
1194 /* Need to emulate with 2 internal calls */
1195
1196 /* Prepare the call_req to be submitted for the MAC step */
1197
1198 if (crq != NULL) {
1199
1200 if (next_req == NULL) {
1201 /*
1202 * allocate, initialize and prepare the
1203 * params for the next step only in the
1204 * first pass (not on every retry).
1205 */
1206 next_req = kcf_alloc_req(crq);
1207
1208 if (next_req == NULL) {
1209 KCF_PROV_REFRELE(pd);
1210 if (list != NULL)
1211 kcf_free_triedlist(list);
1212 return (CRYPTO_HOST_MEMORY);
1213 }
1214 KCF_WRAP_DECRYPT_OPS_PARAMS(
1215 &(next_req->kr_params), KCF_OP_ATOMIC,
1216 NULL, decr_mech, decr_key,
1217 (crypto_data_t *)ct, pt, spi_decr_tmpl);
1218 }
1219
1220 mac_req.cr_flag = (crq != NULL) ? crq->cr_flag : 0;
1221 mac_req.cr_flag |= CRYPTO_SETDUAL;
1222 mac_req.cr_callback_func = kcf_next_req;
1223 mac_req.cr_callback_arg = next_req;
1224 mac_reqp = &mac_req;
1225 }
1226
1227 /* 'pd' is the decryption provider. */
1228
1229 if (do_verify)
1230 error = crypto_mac_verify(mac_mech, (crypto_data_t *)ct,
1231 mac_key, mac_tmpl, mac,
1232 (crq == NULL) ? NULL : mac_reqp);
1233 else
1234 error = crypto_mac(mac_mech, (crypto_data_t *)ct,
1235 mac_key, mac_tmpl, mac,
1236 (crq == NULL) ? NULL : mac_reqp);
1237
1238 switch (error) {
1239 case CRYPTO_SUCCESS: {
1240 off_t saveoffset;
1241 size_t savelen;
1242
1243 if (next_req == NULL) {
1244 saveoffset = ct->dd_offset1;
1245 savelen = ct->dd_len1;
1246 } else {
1247 saveoffset = next_req->kr_saveoffset =
1248 ct->dd_offset1;
1249 savelen = next_req->kr_savelen = ct->dd_len1;
1250
1251 ASSERT(mac_reqp != NULL);
1252 mac_req.cr_flag &= ~CRYPTO_SETDUAL;
1253 mac_req.cr_callback_func = kcf_last_req;
1254 }
1255 ct->dd_offset1 = ct->dd_offset2;
1256 ct->dd_len1 = ct->dd_len2;
1257
1258 if (CHECK_FASTPATH(crq, pd)) {
1259 crypto_mechanism_t lmech;
1260
1261 lmech = *decr_mech;
1262 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type,
1263 pd, &lmech);
1264
1265 error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid,
1266 &lmech, decr_key, (crypto_data_t *)ct,
1267 (crypto_data_t *)pt, spi_decr_tmpl,
1268 KCF_SWFP_RHNDL(mac_reqp));
1269
1270 KCF_PROV_INCRSTATS(pd, error);
1271 } else {
1272 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms,
1273 KCF_OP_ATOMIC, pd->pd_sid, decr_mech,
1274 decr_key, (crypto_data_t *)ct, pt,
1275 spi_decr_tmpl);
1276
1277 error = kcf_submit_request(pd, NULL,
1278 (crq == NULL) ? NULL : mac_reqp,
1279 ¶ms, B_FALSE);
1280 }
1281 if (error != CRYPTO_QUEUED) {
1282 KCF_PROV_INCRSTATS(pd, error);
1283 ct->dd_offset1 = saveoffset;
1284 ct->dd_len1 = savelen;
1285 }
1286 break;
1287 }
1288
1289 case CRYPTO_QUEUED:
1290 if ((crq != NULL) && (crq->cr_flag & CRYPTO_SKIP_REQID))
1291 crq->cr_reqid = mac_req.cr_reqid;
1292 break;
1293
1294 default:
1295 if (IS_RECOVERABLE(error)) {
1296 if (kcf_insert_triedlist(&list, pd,
1297 KCF_KMFLAG(crq)) != NULL)
1298 goto retry;
1299 }
1300 }
1301 if (error != CRYPTO_QUEUED && next_req != NULL)
1302 kmem_free(next_req, sizeof (kcf_dual_req_t));
1303 if (list != NULL)
1304 kcf_free_triedlist(list);
1305 KCF_PROV_REFRELE(pd);
1306 return (error);
1307 }
1308
1309 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
1310 if ((mac_tmpl != NULL) &&
1311 (prov_mac_mechid != CRYPTO_MECH_INVALID)) {
1312 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
1313 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
1314 if (next_req != NULL)
1315 kmem_free(next_req,
1316 sizeof (kcf_dual_req_t));
1317 if (list != NULL)
1318 kcf_free_triedlist(list);
1319 KCF_PROV_REFRELE(pd);
1320
1321 /* Which one is the the old one ? */
1322 return (CRYPTO_OLD_CTX_TEMPLATE);
1323 }
1324 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
1325 }
1326 mac_tmpl_checked = B_TRUE;
1327 }
1328
1329 /* The fast path for SW providers. */
1330 if (CHECK_FASTPATH(crq, pd)) {
1331 crypto_mechanism_t lmac_mech;
1332 crypto_mechanism_t ldecr_mech;
1333
1334 /* careful! structs assignments */
1335 ldecr_mech = *decr_mech;
1336 ldecr_mech.cm_type = prov_decr_mechid;
1337 lmac_mech = *mac_mech;
1338 lmac_mech.cm_type = prov_mac_mechid;
1339
1340 if (do_verify)
1341 error = KCF_PROV_MAC_VERIFY_DECRYPT_ATOMIC(pd,
1342 pd->pd_sid, &lmac_mech, mac_key, &ldecr_mech,
1343 decr_key, ct, mac, pt, spi_mac_tmpl, spi_decr_tmpl,
1344 KCF_SWFP_RHNDL(crq));
1345 else
1346 error = KCF_PROV_MAC_DECRYPT_ATOMIC(pd, pd->pd_sid,
1347 &lmac_mech, mac_key, &ldecr_mech, decr_key,
1348 ct, mac, pt, spi_mac_tmpl, spi_decr_tmpl,
1349 KCF_SWFP_RHNDL(crq));
1350
1351 KCF_PROV_INCRSTATS(pd, error);
1352 } else {
1353 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms,
1354 (do_verify) ? KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC :
1355 KCF_OP_ATOMIC, pd->pd_sid, mac_key, decr_key, ct, mac, pt,
1356 spi_mac_tmpl, spi_decr_tmpl);
1357
1358 cmops = &(params.rp_u.mac_decrypt_params);
1359
1360 /* careful! structs assignments */
1361 cmops->md_decr_mech = *decr_mech;
1362 cmops->md_decr_mech.cm_type = prov_decr_mechid;
1363 cmops->md_framework_decr_mechtype = decr_mech->cm_type;
1364 cmops->md_mac_mech = *mac_mech;
1365 cmops->md_mac_mech.cm_type = prov_mac_mechid;
1366 cmops->md_framework_mac_mechtype = mac_mech->cm_type;
1367
1368 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE);
1369 }
1370
1371 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
1372 IS_RECOVERABLE(error)) {
1373 /* Add pd to the linked list of providers tried. */
1374 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
1375 goto retry;
1376 }
1377
1378 if (list != NULL)
1379 kcf_free_triedlist(list);
1380
1381 if (next_req != NULL)
1382 kmem_free(next_req, sizeof (kcf_dual_req_t));
1383 KCF_PROV_REFRELE(pd);
1384 return (error);
1385 }
1386
1387 static int
crypto_mac_decrypt_common_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_dual_data_t * ct,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_data_t * mac,crypto_data_t * pt,crypto_call_req_t * crq,boolean_t do_verify)1388 crypto_mac_decrypt_common_prov(crypto_provider_t provider,
1389 crypto_session_id_t sid, crypto_mechanism_t *mac_mech,
1390 crypto_mechanism_t *decr_mech, crypto_dual_data_t *ct,
1391 crypto_key_t *mac_key, crypto_key_t *decr_key,
1392 crypto_ctx_template_t mac_tmpl, crypto_ctx_template_t decr_tmpl,
1393 crypto_data_t *mac, crypto_data_t *pt, crypto_call_req_t *crq,
1394 boolean_t do_verify)
1395 {
1396 /*
1397 * First try to find a provider for the decryption mechanism, that
1398 * is also capable of the MAC mechanism.
1399 * We still favor optimizing the costlier decryption.
1400 */
1401 int error;
1402 kcf_mech_entry_t *me;
1403 kcf_provider_desc_t *pd = provider;
1404 kcf_provider_desc_t *real_provider = pd;
1405 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl;
1406 kcf_req_params_t params;
1407 kcf_mac_decrypt_ops_params_t *cmops;
1408 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL;
1409
1410 ASSERT(KCF_PROV_REFHELD(pd));
1411
1412 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
1413 error = kcf_get_hardware_provider(decr_mech->cm_type, decr_key,
1414 mac_mech->cm_type, mac_key, pd, &real_provider,
1415 CRYPTO_FG_MAC_DECRYPT_ATOMIC);
1416
1417 if (error != CRYPTO_SUCCESS)
1418 return (error);
1419 }
1420
1421 /*
1422 * For SW providers, check the validity of the context template
1423 * It is very rare that the generation number mis-matches, so
1424 * is acceptable to fail here, and let the consumer recover by
1425 * freeing this tmpl and create a new one for the key and new SW
1426 * provider
1427 */
1428
1429 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) {
1430 if (decr_tmpl != NULL) {
1431 if (kcf_get_mech_entry(decr_mech->cm_type, &me) !=
1432 KCF_SUCCESS) {
1433 error = CRYPTO_MECHANISM_INVALID;
1434 goto out;
1435 }
1436 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl;
1437 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) {
1438 error = CRYPTO_OLD_CTX_TEMPLATE;
1439 goto out;
1440 }
1441 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl;
1442 }
1443
1444 if (mac_tmpl != NULL) {
1445 if (kcf_get_mech_entry(mac_mech->cm_type, &me) !=
1446 KCF_SUCCESS) {
1447 error = CRYPTO_MECHANISM_INVALID;
1448 goto out;
1449 }
1450 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
1451 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
1452 error = CRYPTO_OLD_CTX_TEMPLATE;
1453 goto out;
1454 }
1455 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
1456 }
1457 }
1458
1459 /* The fast path for SW providers. */
1460 if (CHECK_FASTPATH(crq, pd)) {
1461 crypto_mechanism_t lmac_mech;
1462 crypto_mechanism_t ldecr_mech;
1463
1464 /* careful! structs assignments */
1465 ldecr_mech = *decr_mech;
1466 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider,
1467 &ldecr_mech);
1468
1469 lmac_mech = *mac_mech;
1470 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
1471 &lmac_mech);
1472
1473 if (do_verify)
1474 error = KCF_PROV_MAC_VERIFY_DECRYPT_ATOMIC(
1475 real_provider, sid, &lmac_mech, mac_key,
1476 &ldecr_mech, decr_key, ct, mac, pt, spi_mac_tmpl,
1477 spi_decr_tmpl, KCF_SWFP_RHNDL(crq));
1478 else
1479 error = KCF_PROV_MAC_DECRYPT_ATOMIC(real_provider, sid,
1480 &lmac_mech, mac_key, &ldecr_mech, decr_key,
1481 ct, mac, pt, spi_mac_tmpl, spi_decr_tmpl,
1482 KCF_SWFP_RHNDL(crq));
1483
1484 KCF_PROV_INCRSTATS(pd, error);
1485 } else {
1486 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms,
1487 (do_verify) ? KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC :
1488 KCF_OP_ATOMIC, sid, mac_key, decr_key, ct, mac, pt,
1489 spi_mac_tmpl, spi_decr_tmpl);
1490
1491 cmops = &(params.rp_u.mac_decrypt_params);
1492
1493 /* careful! structs assignments */
1494 cmops->md_decr_mech = *decr_mech;
1495 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider,
1496 &cmops->md_decr_mech);
1497 cmops->md_framework_decr_mechtype = decr_mech->cm_type;
1498
1499 cmops->md_mac_mech = *mac_mech;
1500 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
1501 &cmops->md_mac_mech);
1502 cmops->md_framework_mac_mechtype = mac_mech->cm_type;
1503
1504 error = kcf_submit_request(real_provider, NULL, crq, ¶ms,
1505 B_FALSE);
1506 }
1507
1508 out:
1509 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
1510 KCF_PROV_REFRELE(real_provider);
1511 return (error);
1512 }
1513
1514 /*
1515 * Starts a multi-part dual mac/decrypt operation. The provider to
1516 * use is determined by the KCF dispatcher.
1517 */
1518 /* ARGSUSED */
1519 int
crypto_mac_decrypt_init(crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_context_t * ctxp,crypto_call_req_t * cr)1520 crypto_mac_decrypt_init(crypto_mechanism_t *mac_mech,
1521 crypto_mechanism_t *decr_mech, crypto_key_t *mac_key,
1522 crypto_key_t *decr_key, crypto_ctx_template_t mac_tmpl,
1523 crypto_ctx_template_t decr_tmpl, crypto_context_t *ctxp,
1524 crypto_call_req_t *cr)
1525 {
1526 /*
1527 * First try to find a provider for the decryption mechanism, that
1528 * is also capable of the MAC mechanism.
1529 * We still favor optimizing the costlier decryption.
1530 */
1531 int error;
1532 kcf_mech_entry_t *me;
1533 kcf_provider_desc_t *pd;
1534 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl;
1535 kcf_req_params_t params;
1536 kcf_mac_decrypt_ops_params_t *mdops;
1537 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL;
1538 crypto_mech_type_t prov_decr_mechid, prov_mac_mechid;
1539 kcf_prov_tried_t *list = NULL;
1540 boolean_t decr_tmpl_checked = B_FALSE;
1541 boolean_t mac_tmpl_checked = B_FALSE;
1542 crypto_ctx_t *ctx = NULL;
1543 kcf_context_t *decr_kcf_context = NULL, *mac_kcf_context = NULL;
1544 crypto_call_flag_t save_flag;
1545
1546 retry:
1547 /* pd is returned held on success */
1548 pd = kcf_get_dual_provider(decr_mech, decr_key, mac_mech, mac_key,
1549 &me, &prov_decr_mechid,
1550 &prov_mac_mechid, &error, list,
1551 CRYPTO_FG_DECRYPT | CRYPTO_FG_MAC_DECRYPT, CRYPTO_FG_MAC, 0);
1552 if (pd == NULL) {
1553 if (list != NULL)
1554 kcf_free_triedlist(list);
1555 return (error);
1556 }
1557
1558 /*
1559 * For SW providers, check the validity of the context template
1560 * It is very rare that the generation number mis-matches, so
1561 * is acceptable to fail here, and let the consumer recover by
1562 * freeing this tmpl and create a new one for the key and new SW
1563 * provider
1564 * Warning! will need to change when multiple software providers
1565 * per mechanism are supported.
1566 */
1567
1568 if ((!decr_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
1569 if (decr_tmpl != NULL) {
1570 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl;
1571 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) {
1572
1573 if (list != NULL)
1574 kcf_free_triedlist(list);
1575 if (decr_kcf_context != NULL)
1576 KCF_CONTEXT_REFRELE(decr_kcf_context);
1577
1578 KCF_PROV_REFRELE(pd);
1579 /* Which one is the the old one ? */
1580 return (CRYPTO_OLD_CTX_TEMPLATE);
1581 }
1582 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl;
1583 }
1584 decr_tmpl_checked = B_TRUE;
1585 }
1586
1587 if (prov_mac_mechid == CRYPTO_MECH_INVALID) {
1588 /* Need to emulate with 2 internal calls */
1589
1590 /*
1591 * We avoid code complexity by limiting the pure async.
1592 * case to be done using only a SW provider.
1593 * XXX - Redo the emulation code below so that we can
1594 * remove this limitation.
1595 */
1596 if (cr != NULL && pd->pd_prov_type == CRYPTO_HW_PROVIDER) {
1597 if ((kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr))
1598 != NULL))
1599 goto retry;
1600 if (list != NULL)
1601 kcf_free_triedlist(list);
1602 if (decr_kcf_context != NULL)
1603 KCF_CONTEXT_REFRELE(decr_kcf_context);
1604 KCF_PROV_REFRELE(pd);
1605 return (CRYPTO_HOST_MEMORY);
1606 }
1607
1608 if (ctx == NULL && pd->pd_prov_type == CRYPTO_SW_PROVIDER) {
1609 ctx = kcf_new_ctx(cr, pd, pd->pd_sid);
1610 if (ctx == NULL) {
1611 if (list != NULL)
1612 kcf_free_triedlist(list);
1613 if (decr_kcf_context != NULL)
1614 KCF_CONTEXT_REFRELE(decr_kcf_context);
1615 KCF_PROV_REFRELE(pd);
1616 return (CRYPTO_HOST_MEMORY);
1617 }
1618 decr_kcf_context = (kcf_context_t *)
1619 ctx->cc_framework_private;
1620 }
1621 /*
1622 * Trade-off speed vs avoidance of code complexity and
1623 * duplication:
1624 * Could do all the combinations of fastpath / synch / asynch
1625 * for the decryption and the mac steps. Early attempts
1626 * showed the code grew wild and bug-prone, for little gain.
1627 * Therefore, the adaptative asynch case is not implemented.
1628 * It's either pure synchronous, or pure asynchronous.
1629 * We still preserve a fastpath for the pure synchronous
1630 * requests to SW providers.
1631 */
1632 if (cr == NULL) {
1633 crypto_context_t mac_context;
1634
1635 error = crypto_mac_init(mac_mech, mac_key, mac_tmpl,
1636 &mac_context, NULL);
1637
1638 if (error != CRYPTO_SUCCESS) {
1639 /* Can't be CRYPTO_QUEUED. return the failure */
1640 if (list != NULL)
1641 kcf_free_triedlist(list);
1642
1643 if (decr_kcf_context != NULL)
1644 KCF_CONTEXT_REFRELE(decr_kcf_context);
1645 return (error);
1646 }
1647 if (pd->pd_prov_type == CRYPTO_SW_PROVIDER) {
1648 crypto_mechanism_t lmech = *decr_mech;
1649
1650 lmech.cm_type = prov_decr_mechid;
1651
1652 error = KCF_PROV_DECRYPT_INIT(pd, ctx, &lmech,
1653 decr_key, spi_decr_tmpl,
1654 KCF_RHNDL(KM_SLEEP));
1655 } else {
1656 /*
1657 * If we did the 'goto retry' then ctx may not
1658 * be NULL. In general, we can't reuse another
1659 * provider's context, so we free it now so
1660 * we don't leak it.
1661 */
1662 if (ctx != NULL) {
1663 KCF_CONTEXT_REFRELE((kcf_context_t *)
1664 ctx->cc_framework_private);
1665 decr_kcf_context = NULL;
1666 }
1667 error = crypto_decrypt_init_prov(pd, pd->pd_sid,
1668 decr_mech, decr_key, &decr_tmpl,
1669 (crypto_context_t *)&ctx, NULL);
1670
1671 if (error == CRYPTO_SUCCESS) {
1672 decr_kcf_context = (kcf_context_t *)
1673 ctx->cc_framework_private;
1674 }
1675 }
1676
1677 KCF_PROV_INCRSTATS(pd, error);
1678
1679 KCF_PROV_REFRELE(pd);
1680
1681 if (error != CRYPTO_SUCCESS) {
1682 /* Can't be CRYPTO_QUEUED. return the failure */
1683 if (list != NULL)
1684 kcf_free_triedlist(list);
1685 if (mac_kcf_context != NULL)
1686 KCF_CONTEXT_REFRELE(mac_kcf_context);
1687
1688 return (error);
1689 }
1690 mac_kcf_context = (kcf_context_t *)
1691 ((crypto_ctx_t *)mac_context)->
1692 cc_framework_private;
1693
1694 decr_kcf_context = (kcf_context_t *)
1695 ctx->cc_framework_private;
1696
1697 /*
1698 * Here also, the mac context is second. The callback
1699 * case can't overwrite the context returned to
1700 * the caller.
1701 */
1702 decr_kcf_context->kc_secondctx = mac_kcf_context;
1703 KCF_CONTEXT_REFHOLD(mac_kcf_context);
1704
1705 *ctxp = (crypto_context_t)ctx;
1706
1707 return (error);
1708 }
1709 /* submit a pure asynchronous request. */
1710 save_flag = cr->cr_flag;
1711 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE;
1712
1713 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT,
1714 pd->pd_sid, mac_key, decr_key, NULL, NULL, NULL,
1715 spi_mac_tmpl, spi_decr_tmpl);
1716
1717 mdops = &(params.rp_u.mac_decrypt_params);
1718
1719 /* careful! structs assignments */
1720 mdops->md_decr_mech = *decr_mech;
1721 /*
1722 * mdops->md_decr_mech.cm_type will be set when we get to
1723 * kcf_emulate_dual() routine.
1724 */
1725 mdops->md_framework_decr_mechtype = decr_mech->cm_type;
1726 mdops->md_mac_mech = *mac_mech;
1727
1728 /*
1729 * mdops->md_mac_mech.cm_type will be set when we know the
1730 * MAC provider.
1731 */
1732 mdops->md_framework_mac_mechtype = mac_mech->cm_type;
1733
1734 /*
1735 * non-NULL ctx->kc_secondctx tells common_submit_request
1736 * that this request uses separate cipher and MAC contexts.
1737 * That function will set the MAC context's kc_secondctx to
1738 * this decrypt context.
1739 */
1740 decr_kcf_context->kc_secondctx = decr_kcf_context;
1741
1742 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
1743
1744 cr->cr_flag = save_flag;
1745
1746 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) {
1747 KCF_CONTEXT_REFRELE(decr_kcf_context);
1748 }
1749 if (list != NULL)
1750 kcf_free_triedlist(list);
1751 *ctxp = ctx;
1752 KCF_PROV_REFRELE(pd);
1753 return (error);
1754 }
1755
1756 if ((!mac_tmpl_checked) && (pd->pd_prov_type == CRYPTO_SW_PROVIDER)) {
1757 if ((mac_tmpl != NULL) &&
1758 (prov_mac_mechid != CRYPTO_MECH_INVALID)) {
1759 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
1760 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
1761
1762 if (list != NULL)
1763 kcf_free_triedlist(list);
1764
1765 KCF_PROV_REFRELE(pd);
1766 /* Which one is the the old one ? */
1767 return (CRYPTO_OLD_CTX_TEMPLATE);
1768 }
1769 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
1770 }
1771 mac_tmpl_checked = B_TRUE;
1772 }
1773
1774 if (ctx == NULL) {
1775 ctx = kcf_new_ctx(cr, pd, pd->pd_sid);
1776 if (ctx == NULL) {
1777 error = CRYPTO_HOST_MEMORY;
1778 if (list != NULL)
1779 kcf_free_triedlist(list);
1780 return (CRYPTO_HOST_MEMORY);
1781 }
1782 decr_kcf_context = (kcf_context_t *)ctx->cc_framework_private;
1783 }
1784
1785 /* The fast path for SW providers. */
1786 if (CHECK_FASTPATH(cr, pd)) {
1787 crypto_mechanism_t ldecr_mech;
1788 crypto_mechanism_t lmac_mech;
1789
1790 /* careful! structs assignments */
1791 ldecr_mech = *decr_mech;
1792 ldecr_mech.cm_type = prov_decr_mechid;
1793 lmac_mech = *mac_mech;
1794 lmac_mech.cm_type = prov_mac_mechid;
1795
1796 error = KCF_PROV_MAC_DECRYPT_INIT(pd, ctx, &lmac_mech,
1797 mac_key, &ldecr_mech, decr_key, spi_mac_tmpl, spi_decr_tmpl,
1798 KCF_SWFP_RHNDL(cr));
1799
1800 KCF_PROV_INCRSTATS(pd, error);
1801 } else {
1802 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT,
1803 pd->pd_sid, mac_key, decr_key, NULL, NULL, NULL,
1804 spi_mac_tmpl, spi_decr_tmpl);
1805
1806 mdops = &(params.rp_u.mac_decrypt_params);
1807
1808 /* careful! structs assignments */
1809 mdops->md_decr_mech = *decr_mech;
1810 mdops->md_decr_mech.cm_type = prov_decr_mechid;
1811 mdops->md_framework_decr_mechtype = decr_mech->cm_type;
1812 mdops->md_mac_mech = *mac_mech;
1813 mdops->md_mac_mech.cm_type = prov_mac_mechid;
1814 mdops->md_framework_mac_mechtype = mac_mech->cm_type;
1815
1816 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
1817 }
1818
1819 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED) {
1820 if ((IS_RECOVERABLE(error)) &&
1821 (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(cr)) != NULL))
1822 goto retry;
1823
1824 KCF_CONTEXT_REFRELE(decr_kcf_context);
1825 } else
1826 *ctxp = (crypto_context_t)ctx;
1827
1828 if (list != NULL)
1829 kcf_free_triedlist(list);
1830
1831 KCF_PROV_REFRELE(pd);
1832 return (error);
1833 }
1834
1835 int
crypto_mac_decrypt_init_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mac_mech,crypto_mechanism_t * decr_mech,crypto_key_t * mac_key,crypto_key_t * decr_key,crypto_ctx_template_t mac_tmpl,crypto_ctx_template_t decr_tmpl,crypto_context_t * ctxp,crypto_call_req_t * cr)1836 crypto_mac_decrypt_init_prov(crypto_provider_t provider,
1837 crypto_session_id_t sid, crypto_mechanism_t *mac_mech,
1838 crypto_mechanism_t *decr_mech, crypto_key_t *mac_key,
1839 crypto_key_t *decr_key, crypto_ctx_template_t mac_tmpl,
1840 crypto_ctx_template_t decr_tmpl, crypto_context_t *ctxp,
1841 crypto_call_req_t *cr)
1842 {
1843 /*
1844 * First try to find a provider for the decryption mechanism, that
1845 * is also capable of the MAC mechanism.
1846 * We still favor optimizing the costlier decryption.
1847 */
1848 int rv;
1849 kcf_mech_entry_t *me;
1850 kcf_provider_desc_t *pd = provider;
1851 kcf_provider_desc_t *real_provider = pd;
1852 kcf_ctx_template_t *ctx_decr_tmpl, *ctx_mac_tmpl;
1853 kcf_req_params_t params;
1854 kcf_mac_decrypt_ops_params_t *mdops;
1855 crypto_spi_ctx_template_t spi_decr_tmpl = NULL, spi_mac_tmpl = NULL;
1856 crypto_ctx_t *ctx;
1857 kcf_context_t *decr_kcf_context = NULL;
1858
1859 ASSERT(KCF_PROV_REFHELD(pd));
1860
1861 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
1862 rv = kcf_get_hardware_provider(decr_mech->cm_type, decr_key,
1863 mac_mech->cm_type, mac_key, pd, &real_provider,
1864 CRYPTO_FG_MAC_DECRYPT);
1865
1866 if (rv != CRYPTO_SUCCESS)
1867 return (rv);
1868 }
1869
1870 /*
1871 * For SW providers, check the validity of the context template
1872 * It is very rare that the generation number mis-matches, so
1873 * is acceptable to fail here, and let the consumer recover by
1874 * freeing this tmpl and create a new one for the key and new SW
1875 * provider
1876 * Warning! will need to change when multiple software providers
1877 * per mechanism are supported.
1878 */
1879
1880 if (real_provider->pd_prov_type == CRYPTO_SW_PROVIDER) {
1881 if (decr_tmpl != NULL) {
1882 if (kcf_get_mech_entry(decr_mech->cm_type, &me) !=
1883 KCF_SUCCESS) {
1884 rv = CRYPTO_MECHANISM_INVALID;
1885 goto out;
1886 }
1887 ctx_decr_tmpl = (kcf_ctx_template_t *)decr_tmpl;
1888 if (ctx_decr_tmpl->ct_generation != me->me_gen_swprov) {
1889 rv = CRYPTO_OLD_CTX_TEMPLATE;
1890 goto out;
1891 }
1892 spi_decr_tmpl = ctx_decr_tmpl->ct_prov_tmpl;
1893 }
1894
1895 if (mac_tmpl != NULL) {
1896 if (kcf_get_mech_entry(mac_mech->cm_type, &me) !=
1897 KCF_SUCCESS) {
1898 rv = CRYPTO_MECHANISM_INVALID;
1899 goto out;
1900 }
1901 ctx_mac_tmpl = (kcf_ctx_template_t *)mac_tmpl;
1902 if (ctx_mac_tmpl->ct_generation != me->me_gen_swprov) {
1903 rv = CRYPTO_OLD_CTX_TEMPLATE;
1904 goto out;
1905 }
1906 spi_mac_tmpl = ctx_mac_tmpl->ct_prov_tmpl;
1907 }
1908 }
1909
1910 ctx = kcf_new_ctx(cr, real_provider, sid);
1911 if (ctx == NULL) {
1912 rv = CRYPTO_HOST_MEMORY;
1913 goto out;
1914 }
1915 decr_kcf_context = (kcf_context_t *)ctx->cc_framework_private;
1916
1917 /* The fast path for SW providers. */
1918 if (CHECK_FASTPATH(cr, pd)) {
1919 crypto_mechanism_t ldecr_mech;
1920 crypto_mechanism_t lmac_mech;
1921
1922 /* careful! structs assignments */
1923 ldecr_mech = *decr_mech;
1924 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider,
1925 &ldecr_mech);
1926
1927 lmac_mech = *mac_mech;
1928 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
1929 &lmac_mech);
1930
1931 rv = KCF_PROV_MAC_DECRYPT_INIT(real_provider, ctx, &lmac_mech,
1932 mac_key, &ldecr_mech, decr_key, spi_mac_tmpl, spi_decr_tmpl,
1933 KCF_SWFP_RHNDL(cr));
1934
1935 KCF_PROV_INCRSTATS(pd, rv);
1936 } else {
1937 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT,
1938 sid, mac_key, decr_key, NULL, NULL, NULL,
1939 spi_mac_tmpl, spi_decr_tmpl);
1940
1941 mdops = &(params.rp_u.mac_decrypt_params);
1942
1943 /* careful! structs assignments */
1944 mdops->md_decr_mech = *decr_mech;
1945 KCF_SET_PROVIDER_MECHNUM(decr_mech->cm_type, real_provider,
1946 &mdops->md_decr_mech);
1947 mdops->md_framework_decr_mechtype = decr_mech->cm_type;
1948
1949 mdops->md_mac_mech = *mac_mech;
1950 KCF_SET_PROVIDER_MECHNUM(mac_mech->cm_type, real_provider,
1951 &mdops->md_mac_mech);
1952 mdops->md_framework_mac_mechtype = mac_mech->cm_type;
1953
1954 rv = kcf_submit_request(real_provider, ctx, cr, ¶ms,
1955 B_FALSE);
1956 }
1957
1958 if (rv != CRYPTO_SUCCESS && rv != CRYPTO_QUEUED) {
1959 KCF_CONTEXT_REFRELE(decr_kcf_context);
1960 } else
1961 *ctxp = (crypto_context_t)ctx;
1962
1963 out:
1964 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
1965 KCF_PROV_REFRELE(real_provider);
1966 return (rv);
1967 }
1968 /*
1969 * Continues a multi-part dual mac/decrypt operation.
1970 */
1971 /* ARGSUSED */
1972 int
crypto_mac_decrypt_update(crypto_context_t context,crypto_dual_data_t * ct,crypto_data_t * pt,crypto_call_req_t * cr)1973 crypto_mac_decrypt_update(crypto_context_t context,
1974 crypto_dual_data_t *ct, crypto_data_t *pt, crypto_call_req_t *cr)
1975 {
1976 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx;
1977 kcf_context_t *kcf_ctx, *kcf_mac_ctx;
1978 kcf_provider_desc_t *pd;
1979 int error;
1980 kcf_req_params_t params;
1981
1982 if ((ctx == NULL) ||
1983 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
1984 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
1985 return (CRYPTO_INVALID_CONTEXT);
1986 }
1987
1988 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
1989
1990 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) {
1991 off_t save_offset;
1992 size_t save_len;
1993 crypto_call_flag_t save_flag;
1994
1995 if (kcf_mac_ctx->kc_prov_desc == NULL) {
1996 error = CRYPTO_INVALID_CONTEXT;
1997 goto out;
1998 }
1999 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx;
2000
2001 /* First we submit the MAC request */
2002 if (cr == NULL) {
2003 /*
2004 * 'ct' is always not NULL.
2005 */
2006 error = crypto_mac_update((crypto_context_t)mac_ctx,
2007 (crypto_data_t *)ct, NULL);
2008
2009 if (error != CRYPTO_SUCCESS)
2010 goto out;
2011
2012 /* Decrypt a different length only when told so */
2013
2014 save_offset = ct->dd_offset1;
2015 save_len = ct->dd_len1;
2016
2017 if (ct->dd_len2 > 0) {
2018 ct->dd_offset1 = ct->dd_offset2;
2019 ct->dd_len1 = ct->dd_len2;
2020 }
2021
2022 error = crypto_decrypt_update(context,
2023 (crypto_data_t *)ct, pt, NULL);
2024
2025 ct->dd_offset1 = save_offset;
2026 ct->dd_len1 = save_len;
2027
2028 goto out;
2029 }
2030 /* submit a pure asynchronous request. */
2031 save_flag = cr->cr_flag;
2032 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE;
2033
2034 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE,
2035 pd->pd_sid, NULL, NULL, ct, NULL, pt, NULL, NULL)
2036
2037
2038 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
2039
2040 cr->cr_flag = save_flag;
2041 goto out;
2042 }
2043
2044 /* The fast path for SW providers. */
2045 if (CHECK_FASTPATH(cr, pd)) {
2046 error = KCF_PROV_MAC_DECRYPT_UPDATE(pd, ctx, ct, pt, NULL);
2047 KCF_PROV_INCRSTATS(pd, error);
2048 } else {
2049 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE,
2050 ctx->cc_session, NULL, NULL, ct, NULL, pt, NULL, NULL);
2051
2052 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
2053 }
2054 out:
2055 return (error);
2056 }
2057
2058 /*
2059 * Terminates a multi-part dual mac/decrypt operation.
2060 */
2061 /* ARGSUSED */
2062 int
crypto_mac_decrypt_final(crypto_context_t context,crypto_data_t * mac,crypto_data_t * pt,crypto_call_req_t * cr)2063 crypto_mac_decrypt_final(crypto_context_t context, crypto_data_t *mac,
2064 crypto_data_t *pt, crypto_call_req_t *cr)
2065 {
2066 crypto_ctx_t *ctx = (crypto_ctx_t *)context, *mac_ctx;
2067 kcf_context_t *kcf_ctx, *kcf_mac_ctx;
2068 kcf_provider_desc_t *pd;
2069 int error;
2070 kcf_req_params_t params;
2071
2072 if ((ctx == NULL) ||
2073 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
2074 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
2075 return (CRYPTO_INVALID_CONTEXT);
2076 }
2077
2078 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
2079
2080 if ((kcf_mac_ctx = kcf_ctx->kc_secondctx) != NULL) {
2081 crypto_call_flag_t save_flag;
2082
2083 if (kcf_mac_ctx->kc_prov_desc == NULL) {
2084 error = CRYPTO_INVALID_CONTEXT;
2085 goto out;
2086 }
2087 mac_ctx = &kcf_mac_ctx->kc_glbl_ctx;
2088
2089 /* First we collect the MAC */
2090 if (cr == NULL) {
2091
2092 error = crypto_mac_final((crypto_context_t)mac_ctx,
2093 mac, NULL);
2094
2095 if (error != CRYPTO_SUCCESS) {
2096 crypto_cancel_ctx(ctx);
2097 } else {
2098 /* Get the last chunk of plaintext */
2099 error = crypto_decrypt_final(context, pt, NULL);
2100 }
2101
2102 return (error);
2103 }
2104 /* submit a pure asynchronous request. */
2105 save_flag = cr->cr_flag;
2106 cr->cr_flag |= CRYPTO_ALWAYS_QUEUE;
2107
2108 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL,
2109 pd->pd_sid, NULL, NULL, NULL, mac, pt, NULL, NULL)
2110
2111
2112 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
2113
2114 cr->cr_flag = save_flag;
2115
2116 return (error);
2117 }
2118
2119 /* The fast path for SW providers. */
2120 if (CHECK_FASTPATH(cr, pd)) {
2121 error = KCF_PROV_MAC_DECRYPT_FINAL(pd, ctx, mac, pt, NULL);
2122 KCF_PROV_INCRSTATS(pd, error);
2123 } else {
2124 KCF_WRAP_MAC_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL,
2125 ctx->cc_session, NULL, NULL, NULL, mac, pt, NULL, NULL);
2126
2127 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
2128 }
2129 out:
2130 /* Release the hold done in kcf_new_ctx() during init step. */
2131 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
2132 return (error);
2133 }
2134
2135 /*
2136 * Digest/Encrypt dual operation. Project-private entry point, not part of
2137 * the k-API.
2138 */
2139 /* ARGSUSED */
2140 int
crypto_digest_encrypt_update(crypto_context_t digest_ctx,crypto_context_t encrypt_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_call_req_t * crq)2141 crypto_digest_encrypt_update(crypto_context_t digest_ctx,
2142 crypto_context_t encrypt_ctx, crypto_data_t *plaintext,
2143 crypto_data_t *ciphertext, crypto_call_req_t *crq)
2144 {
2145 /*
2146 * RFE 4688647:
2147 * core functions needed by ioctl interface missing from impl.h
2148 */
2149 return (CRYPTO_NOT_SUPPORTED);
2150 }
2151
2152 /*
2153 * Decrypt/Digest dual operation. Project-private entry point, not part of
2154 * the k-API.
2155 */
2156 /* ARGSUSED */
2157 int
crypto_decrypt_digest_update(crypto_context_t decryptctx,crypto_context_t encrypt_ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_call_req_t * crq)2158 crypto_decrypt_digest_update(crypto_context_t decryptctx,
2159 crypto_context_t encrypt_ctx, crypto_data_t *ciphertext,
2160 crypto_data_t *plaintext, crypto_call_req_t *crq)
2161 {
2162 /*
2163 * RFE 4688647:
2164 * core functions needed by ioctl interface missing from impl.h
2165 */
2166 return (CRYPTO_NOT_SUPPORTED);
2167 }
2168
2169 /*
2170 * Sign/Encrypt dual operation. Project-private entry point, not part of
2171 * the k-API.
2172 */
2173 /* ARGSUSED */
2174 int
crypto_sign_encrypt_update(crypto_context_t sign_ctx,crypto_context_t encrypt_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_call_req_t * crq)2175 crypto_sign_encrypt_update(crypto_context_t sign_ctx,
2176 crypto_context_t encrypt_ctx, crypto_data_t *plaintext,
2177 crypto_data_t *ciphertext, crypto_call_req_t *crq)
2178 {
2179 /*
2180 * RFE 4688647:
2181 * core functions needed by ioctl interface missing from impl.h
2182 */
2183 return (CRYPTO_NOT_SUPPORTED);
2184 }
2185
2186 /*
2187 * Decrypt/Verify dual operation. Project-private entry point, not part of
2188 * the k-API.
2189 */
2190 /* ARGSUSED */
2191 int
crypto_decrypt_verify_update(crypto_context_t decrypt_ctx,crypto_context_t verify_ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_call_req_t * crq)2192 crypto_decrypt_verify_update(crypto_context_t decrypt_ctx,
2193 crypto_context_t verify_ctx, crypto_data_t *ciphertext,
2194 crypto_data_t *plaintext, crypto_call_req_t *crq)
2195 {
2196 /*
2197 * RFE 4688647:
2198 * core functions needed by ioctl interface missing from impl.h
2199 */
2200 return (CRYPTO_NOT_SUPPORTED);
2201 }
2202