]> git.proxmox.com Git - mirror_zfs-debian.git/blob - module/icp/core/kcf_callprov.c
New upstream version 0.7.2
[mirror_zfs-debian.git] / module / icp / core / kcf_callprov.c
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 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/crypto/common.h>
27 #include <sys/crypto/impl.h>
28 #include <sys/crypto/sched_impl.h>
29
30 static int kcf_emulate_dual(kcf_provider_desc_t *, crypto_ctx_t *,
31 kcf_req_params_t *);
32
33 void
34 kcf_free_triedlist(kcf_prov_tried_t *list)
35 {
36 kcf_prov_tried_t *l;
37
38 while ((l = list) != NULL) {
39 list = list->pt_next;
40 KCF_PROV_REFRELE(l->pt_pd);
41 kmem_free(l, sizeof (kcf_prov_tried_t));
42 }
43 }
44
45 kcf_prov_tried_t *
46 kcf_insert_triedlist(kcf_prov_tried_t **list, kcf_provider_desc_t *pd,
47 int kmflag)
48 {
49 kcf_prov_tried_t *l;
50
51 l = kmem_alloc(sizeof (kcf_prov_tried_t), kmflag);
52 if (l == NULL)
53 return (NULL);
54
55 l->pt_pd = pd;
56 l->pt_next = *list;
57 *list = l;
58
59 return (l);
60 }
61
62 static boolean_t
63 is_in_triedlist(kcf_provider_desc_t *pd, kcf_prov_tried_t *triedl)
64 {
65 while (triedl != NULL) {
66 if (triedl->pt_pd == pd)
67 return (B_TRUE);
68 triedl = triedl->pt_next;
69 };
70
71 return (B_FALSE);
72 }
73
74 /*
75 * Search a mech entry's hardware provider list for the specified
76 * provider. Return true if found.
77 */
78 static boolean_t
79 is_valid_provider_for_mech(kcf_provider_desc_t *pd, kcf_mech_entry_t *me,
80 crypto_func_group_t fg)
81 {
82 kcf_prov_mech_desc_t *prov_chain;
83
84 prov_chain = me->me_hw_prov_chain;
85 if (prov_chain != NULL) {
86 ASSERT(me->me_num_hwprov > 0);
87 for (; prov_chain != NULL; prov_chain = prov_chain->pm_next) {
88 if (prov_chain->pm_prov_desc == pd &&
89 IS_FG_SUPPORTED(prov_chain, fg)) {
90 return (B_TRUE);
91 }
92 }
93 }
94 return (B_FALSE);
95 }
96
97 /*
98 * This routine, given a logical provider, returns the least loaded
99 * provider belonging to the logical provider. The provider must be
100 * able to do the specified mechanism, i.e. check that the mechanism
101 * hasn't been disabled. In addition, just in case providers are not
102 * entirely equivalent, the provider's entry point is checked for
103 * non-nullness. This is accomplished by having the caller pass, as
104 * arguments, the offset of the function group (offset_1), and the
105 * offset of the function within the function group (offset_2).
106 * Returns NULL if no provider can be found.
107 */
108 int
109 kcf_get_hardware_provider(crypto_mech_type_t mech_type_1,
110 crypto_mech_type_t mech_type_2, boolean_t call_restrict,
111 kcf_provider_desc_t *old, kcf_provider_desc_t **new, crypto_func_group_t fg)
112 {
113 kcf_provider_desc_t *provider, *real_pd = old;
114 kcf_provider_desc_t *gpd = NULL; /* good provider */
115 kcf_provider_desc_t *bpd = NULL; /* busy provider */
116 kcf_provider_list_t *p;
117 kcf_ops_class_t class;
118 kcf_mech_entry_t *me;
119 kcf_mech_entry_tab_t *me_tab;
120 int index, len, gqlen = INT_MAX, rv = CRYPTO_SUCCESS;
121
122 /* get the mech entry for the specified mechanism */
123 class = KCF_MECH2CLASS(mech_type_1);
124 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) {
125 return (CRYPTO_MECHANISM_INVALID);
126 }
127
128 me_tab = &kcf_mech_tabs_tab[class];
129 index = KCF_MECH2INDEX(mech_type_1);
130 if ((index < 0) || (index >= me_tab->met_size)) {
131 return (CRYPTO_MECHANISM_INVALID);
132 }
133
134 me = &((me_tab->met_tab)[index]);
135 mutex_enter(&me->me_mutex);
136
137 /*
138 * We assume the provider descriptor will not go away because
139 * it is being held somewhere, i.e. its reference count has been
140 * incremented. In the case of the crypto module, the provider
141 * descriptor is held by the session structure.
142 */
143 if (old->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
144 if (old->pd_provider_list == NULL) {
145 real_pd = NULL;
146 rv = CRYPTO_DEVICE_ERROR;
147 goto out;
148 }
149 /*
150 * Find the least loaded real provider. KCF_PROV_LOAD gives
151 * the load (number of pending requests) of the provider.
152 */
153 mutex_enter(&old->pd_lock);
154 p = old->pd_provider_list;
155 while (p != NULL) {
156 provider = p->pl_provider;
157
158 ASSERT(provider->pd_prov_type !=
159 CRYPTO_LOGICAL_PROVIDER);
160
161 if (call_restrict &&
162 (provider->pd_flags & KCF_PROV_RESTRICTED)) {
163 p = p->pl_next;
164 continue;
165 }
166
167 if (!is_valid_provider_for_mech(provider, me, fg)) {
168 p = p->pl_next;
169 continue;
170 }
171
172 /* provider does second mech */
173 if (mech_type_2 != CRYPTO_MECH_INVALID) {
174 int i;
175
176 i = KCF_TO_PROV_MECH_INDX(provider,
177 mech_type_2);
178 if (i == KCF_INVALID_INDX) {
179 p = p->pl_next;
180 continue;
181 }
182 }
183
184 if (provider->pd_state != KCF_PROV_READY) {
185 /* choose BUSY if no READY providers */
186 if (provider->pd_state == KCF_PROV_BUSY)
187 bpd = provider;
188 p = p->pl_next;
189 continue;
190 }
191
192 len = KCF_PROV_LOAD(provider);
193 if (len < gqlen) {
194 gqlen = len;
195 gpd = provider;
196 }
197
198 p = p->pl_next;
199 }
200
201 if (gpd != NULL) {
202 real_pd = gpd;
203 KCF_PROV_REFHOLD(real_pd);
204 } else if (bpd != NULL) {
205 real_pd = bpd;
206 KCF_PROV_REFHOLD(real_pd);
207 } else {
208 /* can't find provider */
209 real_pd = NULL;
210 rv = CRYPTO_MECHANISM_INVALID;
211 }
212 mutex_exit(&old->pd_lock);
213
214 } else {
215 if (!KCF_IS_PROV_USABLE(old) ||
216 (call_restrict && (old->pd_flags & KCF_PROV_RESTRICTED))) {
217 real_pd = NULL;
218 rv = CRYPTO_DEVICE_ERROR;
219 goto out;
220 }
221
222 if (!is_valid_provider_for_mech(old, me, fg)) {
223 real_pd = NULL;
224 rv = CRYPTO_MECHANISM_INVALID;
225 goto out;
226 }
227
228 KCF_PROV_REFHOLD(real_pd);
229 }
230 out:
231 mutex_exit(&me->me_mutex);
232 *new = real_pd;
233 return (rv);
234 }
235
236 /*
237 * Return the best provider for the specified mechanism. The provider
238 * is held and it is the caller's responsibility to release it when done.
239 * The fg input argument is used as a search criterion to pick a provider.
240 * A provider has to support this function group to be picked.
241 *
242 * Find the least loaded provider in the list of providers. We do a linear
243 * search to find one. This is fine as we assume there are only a few
244 * number of providers in this list. If this assumption ever changes,
245 * we should revisit this.
246 *
247 * call_restrict represents if the caller should not be allowed to
248 * use restricted providers.
249 */
250 kcf_provider_desc_t *
251 kcf_get_mech_provider(crypto_mech_type_t mech_type, kcf_mech_entry_t **mepp,
252 int *error, kcf_prov_tried_t *triedl, crypto_func_group_t fg,
253 boolean_t call_restrict, size_t data_size)
254 {
255 kcf_provider_desc_t *pd = NULL, *gpd = NULL;
256 kcf_prov_mech_desc_t *prov_chain, *mdesc;
257 int len, gqlen = INT_MAX;
258 kcf_ops_class_t class;
259 int index;
260 kcf_mech_entry_t *me;
261 kcf_mech_entry_tab_t *me_tab;
262
263 class = KCF_MECH2CLASS(mech_type);
264 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) {
265 *error = CRYPTO_MECHANISM_INVALID;
266 return (NULL);
267 }
268
269 me_tab = &kcf_mech_tabs_tab[class];
270 index = KCF_MECH2INDEX(mech_type);
271 if ((index < 0) || (index >= me_tab->met_size)) {
272 *error = CRYPTO_MECHANISM_INVALID;
273 return (NULL);
274 }
275
276 me = &((me_tab->met_tab)[index]);
277 if (mepp != NULL)
278 *mepp = me;
279
280 mutex_enter(&me->me_mutex);
281
282 prov_chain = me->me_hw_prov_chain;
283
284 /*
285 * We check for the threshold for using a hardware provider for
286 * this amount of data. If there is no software provider available
287 * for the mechanism, then the threshold is ignored.
288 */
289 if ((prov_chain != NULL) &&
290 ((data_size == 0) || (me->me_threshold == 0) ||
291 (data_size >= me->me_threshold) ||
292 ((mdesc = me->me_sw_prov) == NULL) ||
293 (!IS_FG_SUPPORTED(mdesc, fg)) ||
294 (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) {
295 ASSERT(me->me_num_hwprov > 0);
296 /* there is at least one provider */
297
298 /*
299 * Find the least loaded real provider. KCF_PROV_LOAD gives
300 * the load (number of pending requests) of the provider.
301 */
302 while (prov_chain != NULL) {
303 pd = prov_chain->pm_prov_desc;
304
305 if (!IS_FG_SUPPORTED(prov_chain, fg) ||
306 !KCF_IS_PROV_USABLE(pd) ||
307 IS_PROVIDER_TRIED(pd, triedl) ||
308 (call_restrict &&
309 (pd->pd_flags & KCF_PROV_RESTRICTED))) {
310 prov_chain = prov_chain->pm_next;
311 continue;
312 }
313
314 if ((len = KCF_PROV_LOAD(pd)) < gqlen) {
315 gqlen = len;
316 gpd = pd;
317 }
318
319 prov_chain = prov_chain->pm_next;
320 }
321
322 pd = gpd;
323 }
324
325 /* No HW provider for this mech, is there a SW provider? */
326 if (pd == NULL && (mdesc = me->me_sw_prov) != NULL) {
327 pd = mdesc->pm_prov_desc;
328 if (!IS_FG_SUPPORTED(mdesc, fg) ||
329 !KCF_IS_PROV_USABLE(pd) ||
330 IS_PROVIDER_TRIED(pd, triedl) ||
331 (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED)))
332 pd = NULL;
333 }
334
335 if (pd == NULL) {
336 /*
337 * We do not want to report CRYPTO_MECH_NOT_SUPPORTED, when
338 * we are in the "fallback to the next provider" case. Rather
339 * we preserve the error, so that the client gets the right
340 * error code.
341 */
342 if (triedl == NULL)
343 *error = CRYPTO_MECH_NOT_SUPPORTED;
344 } else
345 KCF_PROV_REFHOLD(pd);
346
347 mutex_exit(&me->me_mutex);
348 return (pd);
349 }
350
351 /*
352 * Very similar to kcf_get_mech_provider(). Finds the best provider capable of
353 * a dual operation with both me1 and me2.
354 * When no dual-ops capable providers are available, return the best provider
355 * for me1 only, and sets *prov_mt2 to CRYPTO_INVALID_MECHID;
356 * We assume/expect that a slower HW capable of the dual is still
357 * faster than the 2 fastest providers capable of the individual ops
358 * separately.
359 */
360 kcf_provider_desc_t *
361 kcf_get_dual_provider(crypto_mechanism_t *mech1, crypto_mechanism_t *mech2,
362 kcf_mech_entry_t **mepp, crypto_mech_type_t *prov_mt1,
363 crypto_mech_type_t *prov_mt2, int *error, kcf_prov_tried_t *triedl,
364 crypto_func_group_t fg1, crypto_func_group_t fg2, boolean_t call_restrict,
365 size_t data_size)
366 {
367 kcf_provider_desc_t *pd = NULL, *pdm1 = NULL, *pdm1m2 = NULL;
368 kcf_prov_mech_desc_t *prov_chain, *mdesc;
369 int len, gqlen = INT_MAX, dgqlen = INT_MAX;
370 crypto_mech_info_list_t *mil;
371 crypto_mech_type_t m2id = mech2->cm_type;
372 kcf_mech_entry_t *me;
373
374 /* when mech is a valid mechanism, me will be its mech_entry */
375 if (kcf_get_mech_entry(mech1->cm_type, &me) != KCF_SUCCESS) {
376 *error = CRYPTO_MECHANISM_INVALID;
377 return (NULL);
378 }
379
380 *prov_mt2 = CRYPTO_MECH_INVALID;
381
382 if (mepp != NULL)
383 *mepp = me;
384 mutex_enter(&me->me_mutex);
385
386 prov_chain = me->me_hw_prov_chain;
387 /*
388 * We check the threshold for using a hardware provider for
389 * this amount of data. If there is no software provider available
390 * for the first mechanism, then the threshold is ignored.
391 */
392 if ((prov_chain != NULL) &&
393 ((data_size == 0) || (me->me_threshold == 0) ||
394 (data_size >= me->me_threshold) ||
395 ((mdesc = me->me_sw_prov) == NULL) ||
396 (!IS_FG_SUPPORTED(mdesc, fg1)) ||
397 (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) {
398 /* there is at least one provider */
399 ASSERT(me->me_num_hwprov > 0);
400
401 /*
402 * Find the least loaded provider capable of the combo
403 * me1 + me2, and save a pointer to the least loaded
404 * provider capable of me1 only.
405 */
406 while (prov_chain != NULL) {
407 pd = prov_chain->pm_prov_desc;
408 len = KCF_PROV_LOAD(pd);
409
410 if (!IS_FG_SUPPORTED(prov_chain, fg1) ||
411 !KCF_IS_PROV_USABLE(pd) ||
412 IS_PROVIDER_TRIED(pd, triedl) ||
413 (call_restrict &&
414 (pd->pd_flags & KCF_PROV_RESTRICTED))) {
415 prov_chain = prov_chain->pm_next;
416 continue;
417 }
418
419 /* Save the best provider capable of m1 */
420 if (len < gqlen) {
421 *prov_mt1 =
422 prov_chain->pm_mech_info.cm_mech_number;
423 gqlen = len;
424 pdm1 = pd;
425 }
426
427 /* See if pd can do me2 too */
428 for (mil = prov_chain->pm_mi_list;
429 mil != NULL; mil = mil->ml_next) {
430 if ((mil->ml_mech_info.cm_func_group_mask &
431 fg2) == 0)
432 continue;
433
434 if ((mil->ml_kcf_mechid == m2id) &&
435 (len < dgqlen)) {
436 /* Bingo! */
437 dgqlen = len;
438 pdm1m2 = pd;
439 *prov_mt2 =
440 mil->ml_mech_info.cm_mech_number;
441 *prov_mt1 = prov_chain->
442 pm_mech_info.cm_mech_number;
443 break;
444 }
445 }
446
447 prov_chain = prov_chain->pm_next;
448 }
449
450 pd = (pdm1m2 != NULL) ? pdm1m2 : pdm1;
451 }
452
453 /* no HW provider for this mech, is there a SW provider? */
454 if (pd == NULL && (mdesc = me->me_sw_prov) != NULL) {
455 pd = mdesc->pm_prov_desc;
456 if (!IS_FG_SUPPORTED(mdesc, fg1) ||
457 !KCF_IS_PROV_USABLE(pd) ||
458 IS_PROVIDER_TRIED(pd, triedl) ||
459 (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED)))
460 pd = NULL;
461 else {
462 /* See if pd can do me2 too */
463 for (mil = me->me_sw_prov->pm_mi_list;
464 mil != NULL; mil = mil->ml_next) {
465 if ((mil->ml_mech_info.cm_func_group_mask &
466 fg2) == 0)
467 continue;
468
469 if (mil->ml_kcf_mechid == m2id) {
470 /* Bingo! */
471 *prov_mt2 =
472 mil->ml_mech_info.cm_mech_number;
473 break;
474 }
475 }
476 *prov_mt1 = me->me_sw_prov->pm_mech_info.cm_mech_number;
477 }
478 }
479
480 if (pd == NULL)
481 *error = CRYPTO_MECH_NOT_SUPPORTED;
482 else
483 KCF_PROV_REFHOLD(pd);
484
485 mutex_exit(&me->me_mutex);
486 return (pd);
487 }
488
489 /*
490 * Do the actual work of calling the provider routines.
491 *
492 * pd - Provider structure
493 * ctx - Context for this operation
494 * params - Parameters for this operation
495 * rhndl - Request handle to use for notification
496 *
497 * The return values are the same as that of the respective SPI.
498 */
499 int
500 common_submit_request(kcf_provider_desc_t *pd, crypto_ctx_t *ctx,
501 kcf_req_params_t *params, crypto_req_handle_t rhndl)
502 {
503 int err = CRYPTO_ARGUMENTS_BAD;
504 kcf_op_type_t optype;
505
506 optype = params->rp_optype;
507
508 switch (params->rp_opgrp) {
509 case KCF_OG_DIGEST: {
510 kcf_digest_ops_params_t *dops = &params->rp_u.digest_params;
511
512 switch (optype) {
513 case KCF_OP_INIT:
514 /*
515 * We should do this only here and not in KCF_WRAP_*
516 * macros. This is because we may want to try other
517 * providers, in case we recover from a failure.
518 */
519 KCF_SET_PROVIDER_MECHNUM(dops->do_framework_mechtype,
520 pd, &dops->do_mech);
521
522 err = KCF_PROV_DIGEST_INIT(pd, ctx, &dops->do_mech,
523 rhndl);
524 break;
525
526 case KCF_OP_SINGLE:
527 err = KCF_PROV_DIGEST(pd, ctx, dops->do_data,
528 dops->do_digest, rhndl);
529 break;
530
531 case KCF_OP_UPDATE:
532 err = KCF_PROV_DIGEST_UPDATE(pd, ctx,
533 dops->do_data, rhndl);
534 break;
535
536 case KCF_OP_FINAL:
537 err = KCF_PROV_DIGEST_FINAL(pd, ctx,
538 dops->do_digest, rhndl);
539 break;
540
541 case KCF_OP_ATOMIC:
542 ASSERT(ctx == NULL);
543 KCF_SET_PROVIDER_MECHNUM(dops->do_framework_mechtype,
544 pd, &dops->do_mech);
545 err = KCF_PROV_DIGEST_ATOMIC(pd, dops->do_sid,
546 &dops->do_mech, dops->do_data, dops->do_digest,
547 rhndl);
548 break;
549
550 case KCF_OP_DIGEST_KEY:
551 err = KCF_PROV_DIGEST_KEY(pd, ctx, dops->do_digest_key,
552 rhndl);
553 break;
554
555 default:
556 break;
557 }
558 break;
559 }
560
561 case KCF_OG_MAC: {
562 kcf_mac_ops_params_t *mops = &params->rp_u.mac_params;
563
564 switch (optype) {
565 case KCF_OP_INIT:
566 KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype,
567 pd, &mops->mo_mech);
568
569 err = KCF_PROV_MAC_INIT(pd, ctx, &mops->mo_mech,
570 mops->mo_key, mops->mo_templ, rhndl);
571 break;
572
573 case KCF_OP_SINGLE:
574 err = KCF_PROV_MAC(pd, ctx, mops->mo_data,
575 mops->mo_mac, rhndl);
576 break;
577
578 case KCF_OP_UPDATE:
579 err = KCF_PROV_MAC_UPDATE(pd, ctx, mops->mo_data,
580 rhndl);
581 break;
582
583 case KCF_OP_FINAL:
584 err = KCF_PROV_MAC_FINAL(pd, ctx, mops->mo_mac, rhndl);
585 break;
586
587 case KCF_OP_ATOMIC:
588 ASSERT(ctx == NULL);
589 KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype,
590 pd, &mops->mo_mech);
591
592 err = KCF_PROV_MAC_ATOMIC(pd, mops->mo_sid,
593 &mops->mo_mech, mops->mo_key, mops->mo_data,
594 mops->mo_mac, mops->mo_templ, rhndl);
595 break;
596
597 case KCF_OP_MAC_VERIFY_ATOMIC:
598 ASSERT(ctx == NULL);
599 KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype,
600 pd, &mops->mo_mech);
601
602 err = KCF_PROV_MAC_VERIFY_ATOMIC(pd, mops->mo_sid,
603 &mops->mo_mech, mops->mo_key, mops->mo_data,
604 mops->mo_mac, mops->mo_templ, rhndl);
605 break;
606
607 default:
608 break;
609 }
610 break;
611 }
612
613 case KCF_OG_ENCRYPT: {
614 kcf_encrypt_ops_params_t *eops = &params->rp_u.encrypt_params;
615
616 switch (optype) {
617 case KCF_OP_INIT:
618 KCF_SET_PROVIDER_MECHNUM(eops->eo_framework_mechtype,
619 pd, &eops->eo_mech);
620
621 err = KCF_PROV_ENCRYPT_INIT(pd, ctx, &eops->eo_mech,
622 eops->eo_key, eops->eo_templ, rhndl);
623 break;
624
625 case KCF_OP_SINGLE:
626 err = KCF_PROV_ENCRYPT(pd, ctx, eops->eo_plaintext,
627 eops->eo_ciphertext, rhndl);
628 break;
629
630 case KCF_OP_UPDATE:
631 err = KCF_PROV_ENCRYPT_UPDATE(pd, ctx,
632 eops->eo_plaintext, eops->eo_ciphertext, rhndl);
633 break;
634
635 case KCF_OP_FINAL:
636 err = KCF_PROV_ENCRYPT_FINAL(pd, ctx,
637 eops->eo_ciphertext, rhndl);
638 break;
639
640 case KCF_OP_ATOMIC:
641 ASSERT(ctx == NULL);
642 KCF_SET_PROVIDER_MECHNUM(eops->eo_framework_mechtype,
643 pd, &eops->eo_mech);
644
645 err = KCF_PROV_ENCRYPT_ATOMIC(pd, eops->eo_sid,
646 &eops->eo_mech, eops->eo_key, eops->eo_plaintext,
647 eops->eo_ciphertext, eops->eo_templ, rhndl);
648 break;
649
650 default:
651 break;
652 }
653 break;
654 }
655
656 case KCF_OG_DECRYPT: {
657 kcf_decrypt_ops_params_t *dcrops = &params->rp_u.decrypt_params;
658
659 switch (optype) {
660 case KCF_OP_INIT:
661 KCF_SET_PROVIDER_MECHNUM(dcrops->dop_framework_mechtype,
662 pd, &dcrops->dop_mech);
663
664 err = KCF_PROV_DECRYPT_INIT(pd, ctx, &dcrops->dop_mech,
665 dcrops->dop_key, dcrops->dop_templ, rhndl);
666 break;
667
668 case KCF_OP_SINGLE:
669 err = KCF_PROV_DECRYPT(pd, ctx, dcrops->dop_ciphertext,
670 dcrops->dop_plaintext, rhndl);
671 break;
672
673 case KCF_OP_UPDATE:
674 err = KCF_PROV_DECRYPT_UPDATE(pd, ctx,
675 dcrops->dop_ciphertext, dcrops->dop_plaintext,
676 rhndl);
677 break;
678
679 case KCF_OP_FINAL:
680 err = KCF_PROV_DECRYPT_FINAL(pd, ctx,
681 dcrops->dop_plaintext, rhndl);
682 break;
683
684 case KCF_OP_ATOMIC:
685 ASSERT(ctx == NULL);
686 KCF_SET_PROVIDER_MECHNUM(dcrops->dop_framework_mechtype,
687 pd, &dcrops->dop_mech);
688
689 err = KCF_PROV_DECRYPT_ATOMIC(pd, dcrops->dop_sid,
690 &dcrops->dop_mech, dcrops->dop_key,
691 dcrops->dop_ciphertext, dcrops->dop_plaintext,
692 dcrops->dop_templ, rhndl);
693 break;
694
695 default:
696 break;
697 }
698 break;
699 }
700
701 case KCF_OG_SIGN: {
702 kcf_sign_ops_params_t *sops = &params->rp_u.sign_params;
703
704 switch (optype) {
705 case KCF_OP_INIT:
706 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
707 pd, &sops->so_mech);
708
709 err = KCF_PROV_SIGN_INIT(pd, ctx, &sops->so_mech,
710 sops->so_key, sops->so_templ, rhndl);
711 break;
712
713 case KCF_OP_SIGN_RECOVER_INIT:
714 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
715 pd, &sops->so_mech);
716
717 err = KCF_PROV_SIGN_RECOVER_INIT(pd, ctx,
718 &sops->so_mech, sops->so_key, sops->so_templ,
719 rhndl);
720 break;
721
722 case KCF_OP_SINGLE:
723 err = KCF_PROV_SIGN(pd, ctx, sops->so_data,
724 sops->so_signature, rhndl);
725 break;
726
727 case KCF_OP_SIGN_RECOVER:
728 err = KCF_PROV_SIGN_RECOVER(pd, ctx,
729 sops->so_data, sops->so_signature, rhndl);
730 break;
731
732 case KCF_OP_UPDATE:
733 err = KCF_PROV_SIGN_UPDATE(pd, ctx, sops->so_data,
734 rhndl);
735 break;
736
737 case KCF_OP_FINAL:
738 err = KCF_PROV_SIGN_FINAL(pd, ctx, sops->so_signature,
739 rhndl);
740 break;
741
742 case KCF_OP_ATOMIC:
743 ASSERT(ctx == NULL);
744 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
745 pd, &sops->so_mech);
746
747 err = KCF_PROV_SIGN_ATOMIC(pd, sops->so_sid,
748 &sops->so_mech, sops->so_key, sops->so_data,
749 sops->so_templ, sops->so_signature, rhndl);
750 break;
751
752 case KCF_OP_SIGN_RECOVER_ATOMIC:
753 ASSERT(ctx == NULL);
754 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
755 pd, &sops->so_mech);
756
757 err = KCF_PROV_SIGN_RECOVER_ATOMIC(pd, sops->so_sid,
758 &sops->so_mech, sops->so_key, sops->so_data,
759 sops->so_templ, sops->so_signature, rhndl);
760 break;
761
762 default:
763 break;
764 }
765 break;
766 }
767
768 case KCF_OG_VERIFY: {
769 kcf_verify_ops_params_t *vops = &params->rp_u.verify_params;
770
771 switch (optype) {
772 case KCF_OP_INIT:
773 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
774 pd, &vops->vo_mech);
775
776 err = KCF_PROV_VERIFY_INIT(pd, ctx, &vops->vo_mech,
777 vops->vo_key, vops->vo_templ, rhndl);
778 break;
779
780 case KCF_OP_VERIFY_RECOVER_INIT:
781 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
782 pd, &vops->vo_mech);
783
784 err = KCF_PROV_VERIFY_RECOVER_INIT(pd, ctx,
785 &vops->vo_mech, vops->vo_key, vops->vo_templ,
786 rhndl);
787 break;
788
789 case KCF_OP_SINGLE:
790 err = KCF_PROV_VERIFY(pd, ctx, vops->vo_data,
791 vops->vo_signature, rhndl);
792 break;
793
794 case KCF_OP_VERIFY_RECOVER:
795 err = KCF_PROV_VERIFY_RECOVER(pd, ctx,
796 vops->vo_signature, vops->vo_data, rhndl);
797 break;
798
799 case KCF_OP_UPDATE:
800 err = KCF_PROV_VERIFY_UPDATE(pd, ctx, vops->vo_data,
801 rhndl);
802 break;
803
804 case KCF_OP_FINAL:
805 err = KCF_PROV_VERIFY_FINAL(pd, ctx, vops->vo_signature,
806 rhndl);
807 break;
808
809 case KCF_OP_ATOMIC:
810 ASSERT(ctx == NULL);
811 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
812 pd, &vops->vo_mech);
813
814 err = KCF_PROV_VERIFY_ATOMIC(pd, vops->vo_sid,
815 &vops->vo_mech, vops->vo_key, vops->vo_data,
816 vops->vo_templ, vops->vo_signature, rhndl);
817 break;
818
819 case KCF_OP_VERIFY_RECOVER_ATOMIC:
820 ASSERT(ctx == NULL);
821 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
822 pd, &vops->vo_mech);
823
824 err = KCF_PROV_VERIFY_RECOVER_ATOMIC(pd, vops->vo_sid,
825 &vops->vo_mech, vops->vo_key, vops->vo_signature,
826 vops->vo_templ, vops->vo_data, rhndl);
827 break;
828
829 default:
830 break;
831 }
832 break;
833 }
834
835 case KCF_OG_ENCRYPT_MAC: {
836 kcf_encrypt_mac_ops_params_t *eops =
837 &params->rp_u.encrypt_mac_params;
838 kcf_context_t *kcf_secondctx;
839
840 switch (optype) {
841 case KCF_OP_INIT:
842 kcf_secondctx = ((kcf_context_t *)
843 (ctx->cc_framework_private))->kc_secondctx;
844
845 if (kcf_secondctx != NULL) {
846 err = kcf_emulate_dual(pd, ctx, params);
847 break;
848 }
849 KCF_SET_PROVIDER_MECHNUM(
850 eops->em_framework_encr_mechtype,
851 pd, &eops->em_encr_mech);
852
853 KCF_SET_PROVIDER_MECHNUM(
854 eops->em_framework_mac_mechtype,
855 pd, &eops->em_mac_mech);
856
857 err = KCF_PROV_ENCRYPT_MAC_INIT(pd, ctx,
858 &eops->em_encr_mech, eops->em_encr_key,
859 &eops->em_mac_mech, eops->em_mac_key,
860 eops->em_encr_templ, eops->em_mac_templ,
861 rhndl);
862
863 break;
864
865 case KCF_OP_SINGLE:
866 err = KCF_PROV_ENCRYPT_MAC(pd, ctx,
867 eops->em_plaintext, eops->em_ciphertext,
868 eops->em_mac, rhndl);
869 break;
870
871 case KCF_OP_UPDATE:
872 kcf_secondctx = ((kcf_context_t *)
873 (ctx->cc_framework_private))->kc_secondctx;
874 if (kcf_secondctx != NULL) {
875 err = kcf_emulate_dual(pd, ctx, params);
876 break;
877 }
878 err = KCF_PROV_ENCRYPT_MAC_UPDATE(pd, ctx,
879 eops->em_plaintext, eops->em_ciphertext, rhndl);
880 break;
881
882 case KCF_OP_FINAL:
883 kcf_secondctx = ((kcf_context_t *)
884 (ctx->cc_framework_private))->kc_secondctx;
885 if (kcf_secondctx != NULL) {
886 err = kcf_emulate_dual(pd, ctx, params);
887 break;
888 }
889 err = KCF_PROV_ENCRYPT_MAC_FINAL(pd, ctx,
890 eops->em_ciphertext, eops->em_mac, rhndl);
891 break;
892
893 case KCF_OP_ATOMIC:
894 ASSERT(ctx == NULL);
895
896 KCF_SET_PROVIDER_MECHNUM(
897 eops->em_framework_encr_mechtype,
898 pd, &eops->em_encr_mech);
899
900 KCF_SET_PROVIDER_MECHNUM(
901 eops->em_framework_mac_mechtype,
902 pd, &eops->em_mac_mech);
903
904 err = KCF_PROV_ENCRYPT_MAC_ATOMIC(pd, eops->em_sid,
905 &eops->em_encr_mech, eops->em_encr_key,
906 &eops->em_mac_mech, eops->em_mac_key,
907 eops->em_plaintext, eops->em_ciphertext,
908 eops->em_mac,
909 eops->em_encr_templ, eops->em_mac_templ,
910 rhndl);
911
912 break;
913
914 default:
915 break;
916 }
917 break;
918 }
919
920 case KCF_OG_MAC_DECRYPT: {
921 kcf_mac_decrypt_ops_params_t *dops =
922 &params->rp_u.mac_decrypt_params;
923 kcf_context_t *kcf_secondctx;
924
925 switch (optype) {
926 case KCF_OP_INIT:
927 kcf_secondctx = ((kcf_context_t *)
928 (ctx->cc_framework_private))->kc_secondctx;
929
930 if (kcf_secondctx != NULL) {
931 err = kcf_emulate_dual(pd, ctx, params);
932 break;
933 }
934 KCF_SET_PROVIDER_MECHNUM(
935 dops->md_framework_mac_mechtype,
936 pd, &dops->md_mac_mech);
937
938 KCF_SET_PROVIDER_MECHNUM(
939 dops->md_framework_decr_mechtype,
940 pd, &dops->md_decr_mech);
941
942 err = KCF_PROV_MAC_DECRYPT_INIT(pd, ctx,
943 &dops->md_mac_mech, dops->md_mac_key,
944 &dops->md_decr_mech, dops->md_decr_key,
945 dops->md_mac_templ, dops->md_decr_templ,
946 rhndl);
947
948 break;
949
950 case KCF_OP_SINGLE:
951 err = KCF_PROV_MAC_DECRYPT(pd, ctx,
952 dops->md_ciphertext, dops->md_mac,
953 dops->md_plaintext, rhndl);
954 break;
955
956 case KCF_OP_UPDATE:
957 kcf_secondctx = ((kcf_context_t *)
958 (ctx->cc_framework_private))->kc_secondctx;
959 if (kcf_secondctx != NULL) {
960 err = kcf_emulate_dual(pd, ctx, params);
961 break;
962 }
963 err = KCF_PROV_MAC_DECRYPT_UPDATE(pd, ctx,
964 dops->md_ciphertext, dops->md_plaintext, rhndl);
965 break;
966
967 case KCF_OP_FINAL:
968 kcf_secondctx = ((kcf_context_t *)
969 (ctx->cc_framework_private))->kc_secondctx;
970 if (kcf_secondctx != NULL) {
971 err = kcf_emulate_dual(pd, ctx, params);
972 break;
973 }
974 err = KCF_PROV_MAC_DECRYPT_FINAL(pd, ctx,
975 dops->md_mac, dops->md_plaintext, rhndl);
976 break;
977
978 case KCF_OP_ATOMIC:
979 ASSERT(ctx == NULL);
980
981 KCF_SET_PROVIDER_MECHNUM(
982 dops->md_framework_mac_mechtype,
983 pd, &dops->md_mac_mech);
984
985 KCF_SET_PROVIDER_MECHNUM(
986 dops->md_framework_decr_mechtype,
987 pd, &dops->md_decr_mech);
988
989 err = KCF_PROV_MAC_DECRYPT_ATOMIC(pd, dops->md_sid,
990 &dops->md_mac_mech, dops->md_mac_key,
991 &dops->md_decr_mech, dops->md_decr_key,
992 dops->md_ciphertext, dops->md_mac,
993 dops->md_plaintext,
994 dops->md_mac_templ, dops->md_decr_templ,
995 rhndl);
996
997 break;
998
999 case KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC:
1000 ASSERT(ctx == NULL);
1001
1002 KCF_SET_PROVIDER_MECHNUM(
1003 dops->md_framework_mac_mechtype,
1004 pd, &dops->md_mac_mech);
1005
1006 KCF_SET_PROVIDER_MECHNUM(
1007 dops->md_framework_decr_mechtype,
1008 pd, &dops->md_decr_mech);
1009
1010 err = KCF_PROV_MAC_VERIFY_DECRYPT_ATOMIC(pd,
1011 dops->md_sid, &dops->md_mac_mech, dops->md_mac_key,
1012 &dops->md_decr_mech, dops->md_decr_key,
1013 dops->md_ciphertext, dops->md_mac,
1014 dops->md_plaintext,
1015 dops->md_mac_templ, dops->md_decr_templ,
1016 rhndl);
1017
1018 break;
1019
1020 default:
1021 break;
1022 }
1023 break;
1024 }
1025
1026 case KCF_OG_KEY: {
1027 kcf_key_ops_params_t *kops = &params->rp_u.key_params;
1028
1029 ASSERT(ctx == NULL);
1030 KCF_SET_PROVIDER_MECHNUM(kops->ko_framework_mechtype, pd,
1031 &kops->ko_mech);
1032
1033 switch (optype) {
1034 case KCF_OP_KEY_GENERATE:
1035 err = KCF_PROV_KEY_GENERATE(pd, kops->ko_sid,
1036 &kops->ko_mech,
1037 kops->ko_key_template, kops->ko_key_attribute_count,
1038 kops->ko_key_object_id_ptr, rhndl);
1039 break;
1040
1041 case KCF_OP_KEY_GENERATE_PAIR:
1042 err = KCF_PROV_KEY_GENERATE_PAIR(pd, kops->ko_sid,
1043 &kops->ko_mech,
1044 kops->ko_key_template, kops->ko_key_attribute_count,
1045 kops->ko_private_key_template,
1046 kops->ko_private_key_attribute_count,
1047 kops->ko_key_object_id_ptr,
1048 kops->ko_private_key_object_id_ptr, rhndl);
1049 break;
1050
1051 case KCF_OP_KEY_WRAP:
1052 err = KCF_PROV_KEY_WRAP(pd, kops->ko_sid,
1053 &kops->ko_mech,
1054 kops->ko_key, kops->ko_key_object_id_ptr,
1055 kops->ko_wrapped_key, kops->ko_wrapped_key_len_ptr,
1056 rhndl);
1057 break;
1058
1059 case KCF_OP_KEY_UNWRAP:
1060 err = KCF_PROV_KEY_UNWRAP(pd, kops->ko_sid,
1061 &kops->ko_mech,
1062 kops->ko_key, kops->ko_wrapped_key,
1063 kops->ko_wrapped_key_len_ptr,
1064 kops->ko_key_template, kops->ko_key_attribute_count,
1065 kops->ko_key_object_id_ptr, rhndl);
1066 break;
1067
1068 case KCF_OP_KEY_DERIVE:
1069 err = KCF_PROV_KEY_DERIVE(pd, kops->ko_sid,
1070 &kops->ko_mech,
1071 kops->ko_key, kops->ko_key_template,
1072 kops->ko_key_attribute_count,
1073 kops->ko_key_object_id_ptr, rhndl);
1074 break;
1075
1076 default:
1077 break;
1078 }
1079 break;
1080 }
1081
1082 case KCF_OG_RANDOM: {
1083 kcf_random_number_ops_params_t *rops =
1084 &params->rp_u.random_number_params;
1085
1086 ASSERT(ctx == NULL);
1087
1088 switch (optype) {
1089 case KCF_OP_RANDOM_SEED:
1090 err = KCF_PROV_SEED_RANDOM(pd, rops->rn_sid,
1091 rops->rn_buf, rops->rn_buflen, rops->rn_entropy_est,
1092 rops->rn_flags, rhndl);
1093 break;
1094
1095 case KCF_OP_RANDOM_GENERATE:
1096 err = KCF_PROV_GENERATE_RANDOM(pd, rops->rn_sid,
1097 rops->rn_buf, rops->rn_buflen, rhndl);
1098 break;
1099
1100 default:
1101 break;
1102 }
1103 break;
1104 }
1105
1106 case KCF_OG_SESSION: {
1107 kcf_session_ops_params_t *sops = &params->rp_u.session_params;
1108
1109 ASSERT(ctx == NULL);
1110 switch (optype) {
1111 case KCF_OP_SESSION_OPEN:
1112 /*
1113 * so_pd may be a logical provider, in which case
1114 * we need to check whether it has been removed.
1115 */
1116 if (KCF_IS_PROV_REMOVED(sops->so_pd)) {
1117 err = CRYPTO_DEVICE_ERROR;
1118 break;
1119 }
1120 err = KCF_PROV_SESSION_OPEN(pd, sops->so_sid_ptr,
1121 rhndl, sops->so_pd);
1122 break;
1123
1124 case KCF_OP_SESSION_CLOSE:
1125 /*
1126 * so_pd may be a logical provider, in which case
1127 * we need to check whether it has been removed.
1128 */
1129 if (KCF_IS_PROV_REMOVED(sops->so_pd)) {
1130 err = CRYPTO_DEVICE_ERROR;
1131 break;
1132 }
1133 err = KCF_PROV_SESSION_CLOSE(pd, sops->so_sid,
1134 rhndl, sops->so_pd);
1135 break;
1136
1137 case KCF_OP_SESSION_LOGIN:
1138 err = KCF_PROV_SESSION_LOGIN(pd, sops->so_sid,
1139 sops->so_user_type, sops->so_pin,
1140 sops->so_pin_len, rhndl);
1141 break;
1142
1143 case KCF_OP_SESSION_LOGOUT:
1144 err = KCF_PROV_SESSION_LOGOUT(pd, sops->so_sid, rhndl);
1145 break;
1146
1147 default:
1148 break;
1149 }
1150 break;
1151 }
1152
1153 case KCF_OG_OBJECT: {
1154 kcf_object_ops_params_t *jops = &params->rp_u.object_params;
1155
1156 ASSERT(ctx == NULL);
1157 switch (optype) {
1158 case KCF_OP_OBJECT_CREATE:
1159 err = KCF_PROV_OBJECT_CREATE(pd, jops->oo_sid,
1160 jops->oo_template, jops->oo_attribute_count,
1161 jops->oo_object_id_ptr, rhndl);
1162 break;
1163
1164 case KCF_OP_OBJECT_COPY:
1165 err = KCF_PROV_OBJECT_COPY(pd, jops->oo_sid,
1166 jops->oo_object_id,
1167 jops->oo_template, jops->oo_attribute_count,
1168 jops->oo_object_id_ptr, rhndl);
1169 break;
1170
1171 case KCF_OP_OBJECT_DESTROY:
1172 err = KCF_PROV_OBJECT_DESTROY(pd, jops->oo_sid,
1173 jops->oo_object_id, rhndl);
1174 break;
1175
1176 case KCF_OP_OBJECT_GET_SIZE:
1177 err = KCF_PROV_OBJECT_GET_SIZE(pd, jops->oo_sid,
1178 jops->oo_object_id, jops->oo_object_size, rhndl);
1179 break;
1180
1181 case KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE:
1182 err = KCF_PROV_OBJECT_GET_ATTRIBUTE_VALUE(pd,
1183 jops->oo_sid, jops->oo_object_id,
1184 jops->oo_template, jops->oo_attribute_count, rhndl);
1185 break;
1186
1187 case KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE:
1188 err = KCF_PROV_OBJECT_SET_ATTRIBUTE_VALUE(pd,
1189 jops->oo_sid, jops->oo_object_id,
1190 jops->oo_template, jops->oo_attribute_count, rhndl);
1191 break;
1192
1193 case KCF_OP_OBJECT_FIND_INIT:
1194 err = KCF_PROV_OBJECT_FIND_INIT(pd, jops->oo_sid,
1195 jops->oo_template, jops->oo_attribute_count,
1196 jops->oo_find_init_pp_ptr, rhndl);
1197 break;
1198
1199 case KCF_OP_OBJECT_FIND:
1200 err = KCF_PROV_OBJECT_FIND(pd, jops->oo_find_pp,
1201 jops->oo_object_id_ptr, jops->oo_max_object_count,
1202 jops->oo_object_count_ptr, rhndl);
1203 break;
1204
1205 case KCF_OP_OBJECT_FIND_FINAL:
1206 err = KCF_PROV_OBJECT_FIND_FINAL(pd, jops->oo_find_pp,
1207 rhndl);
1208 break;
1209
1210 default:
1211 break;
1212 }
1213 break;
1214 }
1215
1216 case KCF_OG_PROVMGMT: {
1217 kcf_provmgmt_ops_params_t *pops = &params->rp_u.provmgmt_params;
1218
1219 ASSERT(ctx == NULL);
1220 switch (optype) {
1221 case KCF_OP_MGMT_EXTINFO:
1222 /*
1223 * po_pd may be a logical provider, in which case
1224 * we need to check whether it has been removed.
1225 */
1226 if (KCF_IS_PROV_REMOVED(pops->po_pd)) {
1227 err = CRYPTO_DEVICE_ERROR;
1228 break;
1229 }
1230 err = KCF_PROV_EXT_INFO(pd, pops->po_ext_info, rhndl,
1231 pops->po_pd);
1232 break;
1233
1234 case KCF_OP_MGMT_INITTOKEN:
1235 err = KCF_PROV_INIT_TOKEN(pd, pops->po_pin,
1236 pops->po_pin_len, pops->po_label, rhndl);
1237 break;
1238
1239 case KCF_OP_MGMT_INITPIN:
1240 err = KCF_PROV_INIT_PIN(pd, pops->po_sid, pops->po_pin,
1241 pops->po_pin_len, rhndl);
1242 break;
1243
1244 case KCF_OP_MGMT_SETPIN:
1245 err = KCF_PROV_SET_PIN(pd, pops->po_sid,
1246 pops->po_old_pin, pops->po_old_pin_len,
1247 pops->po_pin, pops->po_pin_len, rhndl);
1248 break;
1249
1250 default:
1251 break;
1252 }
1253 break;
1254 }
1255
1256 case KCF_OG_NOSTORE_KEY: {
1257 kcf_key_ops_params_t *kops = &params->rp_u.key_params;
1258
1259 ASSERT(ctx == NULL);
1260 KCF_SET_PROVIDER_MECHNUM(kops->ko_framework_mechtype, pd,
1261 &kops->ko_mech);
1262
1263 switch (optype) {
1264 case KCF_OP_KEY_GENERATE:
1265 err = KCF_PROV_NOSTORE_KEY_GENERATE(pd, kops->ko_sid,
1266 &kops->ko_mech, kops->ko_key_template,
1267 kops->ko_key_attribute_count,
1268 kops->ko_out_template1,
1269 kops->ko_out_attribute_count1, rhndl);
1270 break;
1271
1272 case KCF_OP_KEY_GENERATE_PAIR:
1273 err = KCF_PROV_NOSTORE_KEY_GENERATE_PAIR(pd,
1274 kops->ko_sid, &kops->ko_mech,
1275 kops->ko_key_template, kops->ko_key_attribute_count,
1276 kops->ko_private_key_template,
1277 kops->ko_private_key_attribute_count,
1278 kops->ko_out_template1,
1279 kops->ko_out_attribute_count1,
1280 kops->ko_out_template2,
1281 kops->ko_out_attribute_count2,
1282 rhndl);
1283 break;
1284
1285 case KCF_OP_KEY_DERIVE:
1286 err = KCF_PROV_NOSTORE_KEY_DERIVE(pd, kops->ko_sid,
1287 &kops->ko_mech, kops->ko_key,
1288 kops->ko_key_template,
1289 kops->ko_key_attribute_count,
1290 kops->ko_out_template1,
1291 kops->ko_out_attribute_count1, rhndl);
1292 break;
1293
1294 default:
1295 break;
1296 }
1297 break;
1298 }
1299 default:
1300 break;
1301 } /* end of switch(params->rp_opgrp) */
1302
1303 KCF_PROV_INCRSTATS(pd, err);
1304 return (err);
1305 }
1306
1307
1308 /*
1309 * Emulate the call for a multipart dual ops with 2 single steps.
1310 * This routine is always called in the context of a working thread
1311 * running kcf_svc_do_run().
1312 * The single steps are submitted in a pure synchronous way (blocking).
1313 * When this routine returns, kcf_svc_do_run() will call kcf_aop_done()
1314 * so the originating consumer's callback gets invoked. kcf_aop_done()
1315 * takes care of freeing the operation context. So, this routine does
1316 * not free the operation context.
1317 *
1318 * The provider descriptor is assumed held by the callers.
1319 */
1320 static int
1321 kcf_emulate_dual(kcf_provider_desc_t *pd, crypto_ctx_t *ctx,
1322 kcf_req_params_t *params)
1323 {
1324 int err = CRYPTO_ARGUMENTS_BAD;
1325 kcf_op_type_t optype;
1326 size_t save_len;
1327 off_t save_offset;
1328
1329 optype = params->rp_optype;
1330
1331 switch (params->rp_opgrp) {
1332 case KCF_OG_ENCRYPT_MAC: {
1333 kcf_encrypt_mac_ops_params_t *cmops =
1334 &params->rp_u.encrypt_mac_params;
1335 kcf_context_t *encr_kcf_ctx;
1336 crypto_ctx_t *mac_ctx;
1337 kcf_req_params_t encr_params;
1338
1339 encr_kcf_ctx = (kcf_context_t *)(ctx->cc_framework_private);
1340
1341 switch (optype) {
1342 case KCF_OP_INIT: {
1343 encr_kcf_ctx->kc_secondctx = NULL;
1344
1345 KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_INIT,
1346 pd->pd_sid, &cmops->em_encr_mech,
1347 cmops->em_encr_key, NULL, NULL,
1348 cmops->em_encr_templ);
1349
1350 err = kcf_submit_request(pd, ctx, NULL, &encr_params,
1351 B_FALSE);
1352
1353 /* It can't be CRYPTO_QUEUED */
1354 if (err != CRYPTO_SUCCESS) {
1355 break;
1356 }
1357
1358 err = crypto_mac_init(&cmops->em_mac_mech,
1359 cmops->em_mac_key, cmops->em_mac_templ,
1360 (crypto_context_t *)&mac_ctx, NULL);
1361
1362 if (err == CRYPTO_SUCCESS) {
1363 encr_kcf_ctx->kc_secondctx = (kcf_context_t *)
1364 mac_ctx->cc_framework_private;
1365 KCF_CONTEXT_REFHOLD((kcf_context_t *)
1366 mac_ctx->cc_framework_private);
1367 }
1368
1369 break;
1370
1371 }
1372 case KCF_OP_UPDATE: {
1373 crypto_dual_data_t *ct = cmops->em_ciphertext;
1374 crypto_data_t *pt = cmops->em_plaintext;
1375 kcf_context_t *mac_kcf_ctx = encr_kcf_ctx->kc_secondctx;
1376 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1377
1378 KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_UPDATE,
1379 pd->pd_sid, NULL, NULL, pt, (crypto_data_t *)ct,
1380 NULL);
1381
1382 err = kcf_submit_request(pd, ctx, NULL, &encr_params,
1383 B_FALSE);
1384
1385 /* It can't be CRYPTO_QUEUED */
1386 if (err != CRYPTO_SUCCESS) {
1387 break;
1388 }
1389
1390 save_offset = ct->dd_offset1;
1391 save_len = ct->dd_len1;
1392 if (ct->dd_len2 == 0) {
1393 /*
1394 * The previous encrypt step was an
1395 * accumulation only and didn't produce any
1396 * partial output
1397 */
1398 if (ct->dd_len1 == 0)
1399 break;
1400
1401 } else {
1402 ct->dd_offset1 = ct->dd_offset2;
1403 ct->dd_len1 = ct->dd_len2;
1404 }
1405 err = crypto_mac_update((crypto_context_t)mac_ctx,
1406 (crypto_data_t *)ct, NULL);
1407
1408 ct->dd_offset1 = save_offset;
1409 ct->dd_len1 = save_len;
1410
1411 break;
1412 }
1413 case KCF_OP_FINAL: {
1414 crypto_dual_data_t *ct = cmops->em_ciphertext;
1415 crypto_data_t *mac = cmops->em_mac;
1416 kcf_context_t *mac_kcf_ctx = encr_kcf_ctx->kc_secondctx;
1417 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1418 crypto_context_t mac_context = mac_ctx;
1419
1420 KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_FINAL,
1421 pd->pd_sid, NULL, NULL, NULL, (crypto_data_t *)ct,
1422 NULL);
1423
1424 err = kcf_submit_request(pd, ctx, NULL, &encr_params,
1425 B_FALSE);
1426
1427 /* It can't be CRYPTO_QUEUED */
1428 if (err != CRYPTO_SUCCESS) {
1429 crypto_cancel_ctx(mac_context);
1430 break;
1431 }
1432
1433 if (ct->dd_len2 > 0) {
1434 save_offset = ct->dd_offset1;
1435 save_len = ct->dd_len1;
1436 ct->dd_offset1 = ct->dd_offset2;
1437 ct->dd_len1 = ct->dd_len2;
1438
1439 err = crypto_mac_update(mac_context,
1440 (crypto_data_t *)ct, NULL);
1441
1442 ct->dd_offset1 = save_offset;
1443 ct->dd_len1 = save_len;
1444
1445 if (err != CRYPTO_SUCCESS) {
1446 crypto_cancel_ctx(mac_context);
1447 return (err);
1448 }
1449 }
1450
1451 /* and finally, collect the MAC */
1452 err = crypto_mac_final(mac_context, mac, NULL);
1453 break;
1454 }
1455
1456 default:
1457 break;
1458 }
1459 KCF_PROV_INCRSTATS(pd, err);
1460 break;
1461 }
1462 case KCF_OG_MAC_DECRYPT: {
1463 kcf_mac_decrypt_ops_params_t *mdops =
1464 &params->rp_u.mac_decrypt_params;
1465 kcf_context_t *decr_kcf_ctx;
1466 crypto_ctx_t *mac_ctx;
1467 kcf_req_params_t decr_params;
1468
1469 decr_kcf_ctx = (kcf_context_t *)(ctx->cc_framework_private);
1470
1471 switch (optype) {
1472 case KCF_OP_INIT: {
1473 decr_kcf_ctx->kc_secondctx = NULL;
1474
1475 err = crypto_mac_init(&mdops->md_mac_mech,
1476 mdops->md_mac_key, mdops->md_mac_templ,
1477 (crypto_context_t *)&mac_ctx, NULL);
1478
1479 /* It can't be CRYPTO_QUEUED */
1480 if (err != CRYPTO_SUCCESS) {
1481 break;
1482 }
1483
1484 KCF_WRAP_DECRYPT_OPS_PARAMS(&decr_params, KCF_OP_INIT,
1485 pd->pd_sid, &mdops->md_decr_mech,
1486 mdops->md_decr_key, NULL, NULL,
1487 mdops->md_decr_templ);
1488
1489 err = kcf_submit_request(pd, ctx, NULL, &decr_params,
1490 B_FALSE);
1491
1492 /* It can't be CRYPTO_QUEUED */
1493 if (err != CRYPTO_SUCCESS) {
1494 crypto_cancel_ctx((crypto_context_t)mac_ctx);
1495 break;
1496 }
1497
1498 decr_kcf_ctx->kc_secondctx = (kcf_context_t *)
1499 mac_ctx->cc_framework_private;
1500 KCF_CONTEXT_REFHOLD((kcf_context_t *)
1501 mac_ctx->cc_framework_private);
1502
1503 break;
1504 default:
1505 break;
1506
1507 }
1508 case KCF_OP_UPDATE: {
1509 crypto_dual_data_t *ct = mdops->md_ciphertext;
1510 crypto_data_t *pt = mdops->md_plaintext;
1511 kcf_context_t *mac_kcf_ctx = decr_kcf_ctx->kc_secondctx;
1512 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1513
1514 err = crypto_mac_update((crypto_context_t)mac_ctx,
1515 (crypto_data_t *)ct, NULL);
1516
1517 if (err != CRYPTO_SUCCESS)
1518 break;
1519
1520 save_offset = ct->dd_offset1;
1521 save_len = ct->dd_len1;
1522
1523 /* zero ct->dd_len2 means decrypt everything */
1524 if (ct->dd_len2 > 0) {
1525 ct->dd_offset1 = ct->dd_offset2;
1526 ct->dd_len1 = ct->dd_len2;
1527 }
1528
1529 err = crypto_decrypt_update((crypto_context_t)ctx,
1530 (crypto_data_t *)ct, pt, NULL);
1531
1532 ct->dd_offset1 = save_offset;
1533 ct->dd_len1 = save_len;
1534
1535 break;
1536 }
1537 case KCF_OP_FINAL: {
1538 crypto_data_t *pt = mdops->md_plaintext;
1539 crypto_data_t *mac = mdops->md_mac;
1540 kcf_context_t *mac_kcf_ctx = decr_kcf_ctx->kc_secondctx;
1541 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1542
1543 err = crypto_mac_final((crypto_context_t)mac_ctx,
1544 mac, NULL);
1545
1546 if (err != CRYPTO_SUCCESS) {
1547 crypto_cancel_ctx(ctx);
1548 break;
1549 }
1550
1551 /* Get the last chunk of plaintext */
1552 KCF_CONTEXT_REFHOLD(decr_kcf_ctx);
1553 err = crypto_decrypt_final((crypto_context_t)ctx, pt,
1554 NULL);
1555
1556 break;
1557 }
1558 }
1559 break;
1560 }
1561 default:
1562
1563 break;
1564 } /* end of switch(params->rp_opgrp) */
1565
1566 return (err);
1567 }