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.
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.
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]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/zfs_context.h>
27 #include <sys/crypto/common.h>
28 #include <sys/crypto/impl.h>
29 #include <sys/crypto/api.h>
30 #include <sys/crypto/spi.h>
31 #include <sys/crypto/sched_impl.h>
33 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f)
34 #define CRYPTO_CIPHER_OFFSET(f) offsetof(crypto_cipher_ops_t, f)
37 * Encryption and decryption routines.
41 * The following are the possible returned values common to all the routines
42 * below. The applicability of some of these return values depends on the
43 * presence of the arguments.
45 * CRYPTO_SUCCESS: The operation completed successfully.
46 * CRYPTO_QUEUED: A request was submitted successfully. The callback
47 * routine will be called when the operation is done.
48 * CRYPTO_INVALID_MECH_NUMBER, CRYPTO_INVALID_MECH_PARAM, or
49 * CRYPTO_INVALID_MECH for problems with the 'mech'.
50 * CRYPTO_INVALID_DATA for bogus 'data'
51 * CRYPTO_HOST_MEMORY for failure to allocate memory to handle this work.
52 * CRYPTO_INVALID_CONTEXT: Not a valid context.
53 * CRYPTO_BUSY: Cannot process the request now. Schedule a
54 * crypto_bufcall(), or try later.
55 * CRYPTO_NOT_SUPPORTED and CRYPTO_MECH_NOT_SUPPORTED: No provider is
56 * capable of a function or a mechanism.
57 * CRYPTO_INVALID_KEY: bogus 'key' argument.
58 * CRYPTO_INVALID_PLAINTEXT: bogus 'plaintext' argument.
59 * CRYPTO_INVALID_CIPHERTEXT: bogus 'ciphertext' argument.
63 * crypto_cipher_init_prov()
67 * pd: provider descriptor
69 * mech: crypto_mechanism_t pointer.
70 * mech_type is a valid value previously returned by
72 * When the mech's parameter is not NULL, its definition depends
73 * on the standard definition of the mechanism.
74 * key: pointer to a crypto_key_t structure.
75 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
76 * encryption or decryption with the 'mech' using 'key'.
77 * 'tmpl' is created by a previous call to
78 * crypto_create_ctx_template().
79 * ctxp: Pointer to a crypto_context_t.
80 * func: CRYPTO_FG_ENCRYPT or CRYPTO_FG_DECRYPT.
81 * cr: crypto_call_req_t calling conditions and call back info.
84 * This is a common function invoked internally by both
85 * crypto_encrypt_init() and crypto_decrypt_init().
86 * Asynchronously submits a request for, or synchronously performs the
87 * initialization of an encryption or a decryption operation.
88 * When possible and applicable, will internally use the pre-expanded key
89 * schedule from the context template, tmpl.
90 * When complete and successful, 'ctxp' will contain a crypto_context_t
91 * valid for later calls to encrypt_update() and encrypt_final(), or
92 * decrypt_update() and decrypt_final().
93 * The caller should hold a reference on the specified provider
94 * descriptor before calling this function.
97 * Process or interrupt, according to the semantics dictated by the 'cr'.
100 * See comment in the beginning of the file.
103 crypto_cipher_init_prov(crypto_provider_t provider, crypto_session_id_t sid,
104 crypto_mechanism_t *mech, crypto_key_t *key,
105 crypto_spi_ctx_template_t tmpl, crypto_context_t *ctxp,
106 crypto_call_req_t *crq, crypto_func_group_t func)
110 kcf_req_params_t params;
111 kcf_provider_desc_t *pd = provider;
112 kcf_provider_desc_t *real_provider = pd;
114 ASSERT(KCF_PROV_REFHELD(pd));
116 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
117 if (func == CRYPTO_FG_ENCRYPT) {
118 error = kcf_get_hardware_provider(mech->cm_type,
119 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
120 &real_provider, CRYPTO_FG_ENCRYPT);
122 error = kcf_get_hardware_provider(mech->cm_type,
123 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
124 &real_provider, CRYPTO_FG_DECRYPT);
127 if (error != CRYPTO_SUCCESS)
131 /* Allocate and initialize the canonical context */
132 if ((ctx = kcf_new_ctx(crq, real_provider, sid)) == NULL) {
133 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
134 KCF_PROV_REFRELE(real_provider);
135 return (CRYPTO_HOST_MEMORY);
138 /* The fast path for SW providers. */
139 if (CHECK_FASTPATH(crq, pd)) {
140 crypto_mechanism_t lmech;
143 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech);
145 if (func == CRYPTO_FG_ENCRYPT)
146 error = KCF_PROV_ENCRYPT_INIT(real_provider, ctx,
147 &lmech, key, tmpl, KCF_SWFP_RHNDL(crq));
149 ASSERT(func == CRYPTO_FG_DECRYPT);
151 error = KCF_PROV_DECRYPT_INIT(real_provider, ctx,
152 &lmech, key, tmpl, KCF_SWFP_RHNDL(crq));
154 KCF_PROV_INCRSTATS(pd, error);
159 /* Check if context sharing is possible */
160 if (pd->pd_prov_type == CRYPTO_HW_PROVIDER &&
161 key->ck_format == CRYPTO_KEY_RAW &&
162 KCF_CAN_SHARE_OPSTATE(pd, mech->cm_type)) {
163 kcf_context_t *tctxp = (kcf_context_t *)ctx;
164 kcf_provider_desc_t *tpd = NULL;
165 crypto_mech_info_t *sinfo;
167 if ((kcf_get_sw_prov(mech->cm_type, &tpd, &tctxp->kc_mech,
168 B_FALSE) == CRYPTO_SUCCESS)) {
171 sinfo = &(KCF_TO_PROV_MECHINFO(tpd, mech->cm_type));
173 * key->ck_length from the consumer is always in bits.
174 * We convert it to be in the same unit registered by
175 * the provider in order to do a comparison.
177 if (sinfo->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES)
178 tlen = key->ck_length >> 3;
180 tlen = key->ck_length;
182 * Check if the software provider can support context
183 * sharing and support this key length.
185 if ((sinfo->cm_mech_flags & CRYPTO_CAN_SHARE_OPSTATE) &&
186 (tlen >= sinfo->cm_min_key_length) &&
187 (tlen <= sinfo->cm_max_key_length)) {
188 ctx->cc_flags = CRYPTO_INIT_OPSTATE;
189 tctxp->kc_sw_prov_desc = tpd;
191 KCF_PROV_REFRELE(tpd);
195 if (func == CRYPTO_FG_ENCRYPT) {
196 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid,
197 mech, key, NULL, NULL, tmpl);
199 ASSERT(func == CRYPTO_FG_DECRYPT);
200 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid,
201 mech, key, NULL, NULL, tmpl);
204 error = kcf_submit_request(real_provider, ctx, crq, ¶ms,
207 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
208 KCF_PROV_REFRELE(real_provider);
211 if ((error == CRYPTO_SUCCESS) || (error == CRYPTO_QUEUED))
212 *ctxp = (crypto_context_t)ctx;
214 /* Release the hold done in kcf_new_ctx(). */
215 KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private);
222 * Same as crypto_cipher_init_prov(), but relies on the scheduler to pick
223 * an appropriate provider. See crypto_cipher_init_prov() comments for more
227 crypto_cipher_init(crypto_mechanism_t *mech, crypto_key_t *key,
228 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
229 crypto_call_req_t *crq, crypto_func_group_t func)
232 kcf_mech_entry_t *me;
233 kcf_provider_desc_t *pd;
234 kcf_ctx_template_t *ctx_tmpl;
235 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
236 kcf_prov_tried_t *list = NULL;
239 /* pd is returned held */
240 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
241 list, func, CHECK_RESTRICT(crq), 0)) == NULL) {
243 kcf_free_triedlist(list);
248 * For SW providers, check the validity of the context template
249 * It is very rare that the generation number mis-matches, so
250 * is acceptable to fail here, and let the consumer recover by
251 * freeing this tmpl and create a new one for the key and new SW
254 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
255 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
256 if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
258 kcf_free_triedlist(list);
259 KCF_PROV_REFRELE(pd);
260 return (CRYPTO_OLD_CTX_TEMPLATE);
262 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
266 error = crypto_cipher_init_prov(pd, pd->pd_sid, mech, key,
267 spi_ctx_tmpl, ctxp, crq, func);
268 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
269 IS_RECOVERABLE(error)) {
270 /* Add pd to the linked list of providers tried. */
271 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
276 kcf_free_triedlist(list);
278 KCF_PROV_REFRELE(pd);
283 * crypto_encrypt_prov()
286 * pd: provider descriptor
288 * mech: crypto_mechanism_t pointer.
289 * mech_type is a valid value previously returned by
291 * When the mech's parameter is not NULL, its definition depends
292 * on the standard definition of the mechanism.
293 * key: pointer to a crypto_key_t structure.
294 * plaintext: The message to be encrypted
295 * ciphertext: Storage for the encrypted message. The length needed
296 * depends on the mechanism, and the plaintext's size.
297 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
298 * encryption with the 'mech' using 'key'. 'tmpl' is created by
299 * a previous call to crypto_create_ctx_template().
300 * cr: crypto_call_req_t calling conditions and call back info.
303 * Asynchronously submits a request for, or synchronously performs a
304 * single-part encryption of 'plaintext' with the mechanism 'mech', using
306 * When complete and successful, 'ciphertext' will contain the encrypted
310 * Process or interrupt, according to the semantics dictated by the 'cr'.
313 * See comment in the beginning of the file.
316 crypto_encrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
317 crypto_mechanism_t *mech, crypto_data_t *plaintext, crypto_key_t *key,
318 crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
319 crypto_call_req_t *crq)
321 kcf_req_params_t params;
322 kcf_provider_desc_t *pd = provider;
323 kcf_provider_desc_t *real_provider = pd;
326 ASSERT(KCF_PROV_REFHELD(pd));
328 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
329 error = kcf_get_hardware_provider(mech->cm_type,
330 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
331 &real_provider, CRYPTO_FG_ENCRYPT_ATOMIC);
333 if (error != CRYPTO_SUCCESS)
337 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, sid, mech, key,
338 plaintext, ciphertext, tmpl);
340 error = kcf_submit_request(real_provider, NULL, crq, ¶ms, B_FALSE);
341 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
342 KCF_PROV_REFRELE(real_provider);
348 * Same as crypto_encrypt_prov(), but relies on the scheduler to pick
349 * a provider. See crypto_encrypt_prov() for more details.
352 crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext,
353 crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
354 crypto_call_req_t *crq)
357 kcf_mech_entry_t *me;
358 kcf_req_params_t params;
359 kcf_provider_desc_t *pd;
360 kcf_ctx_template_t *ctx_tmpl;
361 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
362 kcf_prov_tried_t *list = NULL;
365 /* pd is returned held */
366 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
367 list, CRYPTO_FG_ENCRYPT_ATOMIC, CHECK_RESTRICT(crq),
368 plaintext->cd_length)) == NULL) {
370 kcf_free_triedlist(list);
375 * For SW providers, check the validity of the context template
376 * It is very rare that the generation number mis-matches, so
377 * is acceptable to fail here, and let the consumer recover by
378 * freeing this tmpl and create a new one for the key and new SW
381 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
382 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
383 if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
385 kcf_free_triedlist(list);
386 KCF_PROV_REFRELE(pd);
387 return (CRYPTO_OLD_CTX_TEMPLATE);
389 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
393 /* The fast path for SW providers. */
394 if (CHECK_FASTPATH(crq, pd)) {
395 crypto_mechanism_t lmech;
398 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
400 error = KCF_PROV_ENCRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
401 plaintext, ciphertext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
402 KCF_PROV_INCRSTATS(pd, error);
404 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, pd->pd_sid,
405 mech, key, plaintext, ciphertext, spi_ctx_tmpl);
406 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE);
409 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
410 IS_RECOVERABLE(error)) {
411 /* Add pd to the linked list of providers tried. */
412 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
417 kcf_free_triedlist(list);
419 KCF_PROV_REFRELE(pd);
424 * crypto_encrypt_init_prov()
426 * Calls crypto_cipher_init_prov() to initialize an encryption operation.
429 crypto_encrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
430 crypto_mechanism_t *mech, crypto_key_t *key,
431 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
432 crypto_call_req_t *crq)
434 return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
439 * crypto_encrypt_init()
441 * Calls crypto_cipher_init() to initialize an encryption operation
444 crypto_encrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
445 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
446 crypto_call_req_t *crq)
448 return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
453 * crypto_encrypt_update()
456 * context: A crypto_context_t initialized by encrypt_init().
457 * plaintext: The message part to be encrypted
458 * ciphertext: Storage for the encrypted message part.
459 * cr: crypto_call_req_t calling conditions and call back info.
462 * Asynchronously submits a request for, or synchronously performs a
463 * part of an encryption operation.
466 * Process or interrupt, according to the semantics dictated by the 'cr'.
469 * See comment in the beginning of the file.
472 crypto_encrypt_update(crypto_context_t context, crypto_data_t *plaintext,
473 crypto_data_t *ciphertext, crypto_call_req_t *cr)
475 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
476 kcf_context_t *kcf_ctx;
477 kcf_provider_desc_t *pd;
479 kcf_req_params_t params;
482 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
483 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
484 return (CRYPTO_INVALID_CONTEXT);
487 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
489 /* The fast path for SW providers. */
490 if (CHECK_FASTPATH(cr, pd)) {
491 error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext,
493 KCF_PROV_INCRSTATS(pd, error);
497 /* Check if we should use a software provider for small jobs */
498 if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) {
499 if (plaintext->cd_length < kcf_ctx->kc_mech->me_threshold &&
500 kcf_ctx->kc_sw_prov_desc != NULL &&
501 KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) {
502 pd = kcf_ctx->kc_sw_prov_desc;
506 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE,
507 ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL);
508 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
514 * crypto_encrypt_final()
517 * context: A crypto_context_t initialized by encrypt_init().
518 * ciphertext: Storage for the last part of encrypted message
519 * cr: crypto_call_req_t calling conditions and call back info.
522 * Asynchronously submits a request for, or synchronously performs the
523 * final part of an encryption operation.
526 * Process or interrupt, according to the semantics dictated by the 'cr'.
529 * See comment in the beginning of the file.
532 crypto_encrypt_final(crypto_context_t context, crypto_data_t *ciphertext,
533 crypto_call_req_t *cr)
535 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
536 kcf_context_t *kcf_ctx;
537 kcf_provider_desc_t *pd;
539 kcf_req_params_t params;
542 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
543 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
544 return (CRYPTO_INVALID_CONTEXT);
547 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
549 /* The fast path for SW providers. */
550 if (CHECK_FASTPATH(cr, pd)) {
551 error = KCF_PROV_ENCRYPT_FINAL(pd, ctx, ciphertext, NULL);
552 KCF_PROV_INCRSTATS(pd, error);
554 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL,
555 ctx->cc_session, NULL, NULL, NULL, ciphertext, NULL);
556 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
559 /* Release the hold done in kcf_new_ctx() during init step. */
560 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
565 * crypto_decrypt_prov()
568 * pd: provider descriptor
570 * mech: crypto_mechanism_t pointer.
571 * mech_type is a valid value previously returned by
573 * When the mech's parameter is not NULL, its definition depends
574 * on the standard definition of the mechanism.
575 * key: pointer to a crypto_key_t structure.
576 * ciphertext: The message to be encrypted
577 * plaintext: Storage for the encrypted message. The length needed
578 * depends on the mechanism, and the plaintext's size.
579 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
580 * encryption with the 'mech' using 'key'. 'tmpl' is created by
581 * a previous call to crypto_create_ctx_template().
582 * cr: crypto_call_req_t calling conditions and call back info.
585 * Asynchronously submits a request for, or synchronously performs a
586 * single-part decryption of 'ciphertext' with the mechanism 'mech', using
588 * When complete and successful, 'plaintext' will contain the decrypted
592 * Process or interrupt, according to the semantics dictated by the 'cr'.
595 * See comment in the beginning of the file.
598 crypto_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
599 crypto_mechanism_t *mech, crypto_data_t *ciphertext, crypto_key_t *key,
600 crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
601 crypto_call_req_t *crq)
603 kcf_req_params_t params;
604 kcf_provider_desc_t *pd = provider;
605 kcf_provider_desc_t *real_provider = pd;
608 ASSERT(KCF_PROV_REFHELD(pd));
610 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
611 rv = kcf_get_hardware_provider(mech->cm_type,
612 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
613 &real_provider, CRYPTO_FG_DECRYPT_ATOMIC);
615 if (rv != CRYPTO_SUCCESS)
619 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, sid, mech, key,
620 ciphertext, plaintext, tmpl);
622 rv = kcf_submit_request(real_provider, NULL, crq, ¶ms, B_FALSE);
623 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
624 KCF_PROV_REFRELE(real_provider);
630 * Same as crypto_decrypt_prov(), but relies on the KCF scheduler to
631 * choose a provider. See crypto_decrypt_prov() comments for more
635 crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext,
636 crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
637 crypto_call_req_t *crq)
640 kcf_mech_entry_t *me;
641 kcf_req_params_t params;
642 kcf_provider_desc_t *pd;
643 kcf_ctx_template_t *ctx_tmpl;
644 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
645 kcf_prov_tried_t *list = NULL;
648 /* pd is returned held */
649 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
650 list, CRYPTO_FG_DECRYPT_ATOMIC, CHECK_RESTRICT(crq),
651 ciphertext->cd_length)) == NULL) {
653 kcf_free_triedlist(list);
658 * For SW providers, check the validity of the context template
659 * It is very rare that the generation number mis-matches, so
660 * is acceptable to fail here, and let the consumer recover by
661 * freeing this tmpl and create a new one for the key and new SW
664 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
665 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
666 if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
668 kcf_free_triedlist(list);
669 KCF_PROV_REFRELE(pd);
670 return (CRYPTO_OLD_CTX_TEMPLATE);
672 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
676 /* The fast path for SW providers. */
677 if (CHECK_FASTPATH(crq, pd)) {
678 crypto_mechanism_t lmech;
681 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
683 error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
684 ciphertext, plaintext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
685 KCF_PROV_INCRSTATS(pd, error);
687 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_ATOMIC, pd->pd_sid,
688 mech, key, ciphertext, plaintext, spi_ctx_tmpl);
689 error = kcf_submit_request(pd, NULL, crq, ¶ms, B_FALSE);
692 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
693 IS_RECOVERABLE(error)) {
694 /* Add pd to the linked list of providers tried. */
695 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
700 kcf_free_triedlist(list);
702 KCF_PROV_REFRELE(pd);
707 * crypto_decrypt_init_prov()
709 * Calls crypto_cipher_init_prov() to initialize a decryption operation
712 crypto_decrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
713 crypto_mechanism_t *mech, crypto_key_t *key,
714 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
715 crypto_call_req_t *crq)
717 return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
722 * crypto_decrypt_init()
724 * Calls crypto_cipher_init() to initialize a decryption operation
727 crypto_decrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
728 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
729 crypto_call_req_t *crq)
731 return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
736 * crypto_decrypt_update()
739 * context: A crypto_context_t initialized by decrypt_init().
740 * ciphertext: The message part to be decrypted
741 * plaintext: Storage for the decrypted message part.
742 * cr: crypto_call_req_t calling conditions and call back info.
745 * Asynchronously submits a request for, or synchronously performs a
746 * part of an decryption operation.
749 * Process or interrupt, according to the semantics dictated by the 'cr'.
752 * See comment in the beginning of the file.
755 crypto_decrypt_update(crypto_context_t context, crypto_data_t *ciphertext,
756 crypto_data_t *plaintext, crypto_call_req_t *cr)
758 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
759 kcf_context_t *kcf_ctx;
760 kcf_provider_desc_t *pd;
762 kcf_req_params_t params;
765 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
766 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
767 return (CRYPTO_INVALID_CONTEXT);
770 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
772 /* The fast path for SW providers. */
773 if (CHECK_FASTPATH(cr, pd)) {
774 error = KCF_PROV_DECRYPT_UPDATE(pd, ctx, ciphertext,
776 KCF_PROV_INCRSTATS(pd, error);
780 /* Check if we should use a software provider for small jobs */
781 if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) {
782 if (ciphertext->cd_length < kcf_ctx->kc_mech->me_threshold &&
783 kcf_ctx->kc_sw_prov_desc != NULL &&
784 KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) {
785 pd = kcf_ctx->kc_sw_prov_desc;
789 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE,
790 ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL);
791 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
797 * crypto_decrypt_final()
800 * context: A crypto_context_t initialized by decrypt_init().
801 * plaintext: Storage for the last part of the decrypted message
802 * cr: crypto_call_req_t calling conditions and call back info.
805 * Asynchronously submits a request for, or synchronously performs the
806 * final part of a decryption operation.
809 * Process or interrupt, according to the semantics dictated by the 'cr'.
812 * See comment in the beginning of the file.
815 crypto_decrypt_final(crypto_context_t context, crypto_data_t *plaintext,
816 crypto_call_req_t *cr)
818 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
819 kcf_context_t *kcf_ctx;
820 kcf_provider_desc_t *pd;
822 kcf_req_params_t params;
825 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
826 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
827 return (CRYPTO_INVALID_CONTEXT);
830 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
832 /* The fast path for SW providers. */
833 if (CHECK_FASTPATH(cr, pd)) {
834 error = KCF_PROV_DECRYPT_FINAL(pd, ctx, plaintext,
836 KCF_PROV_INCRSTATS(pd, error);
838 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_FINAL,
839 ctx->cc_session, NULL, NULL, NULL, plaintext, NULL);
840 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
843 /* Release the hold done in kcf_new_ctx() during init step. */
844 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
849 * See comments for crypto_encrypt_update().
852 crypto_encrypt_single(crypto_context_t context, crypto_data_t *plaintext,
853 crypto_data_t *ciphertext, crypto_call_req_t *cr)
855 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
856 kcf_context_t *kcf_ctx;
857 kcf_provider_desc_t *pd;
859 kcf_req_params_t params;
862 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
863 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
864 return (CRYPTO_INVALID_CONTEXT);
867 /* The fast path for SW providers. */
868 if (CHECK_FASTPATH(cr, pd)) {
869 error = KCF_PROV_ENCRYPT(pd, ctx, plaintext,
871 KCF_PROV_INCRSTATS(pd, error);
873 KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_SINGLE, pd->pd_sid,
874 NULL, NULL, plaintext, ciphertext, NULL);
875 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
878 /* Release the hold done in kcf_new_ctx() during init step. */
879 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
884 * See comments for crypto_decrypt_update().
887 crypto_decrypt_single(crypto_context_t context, crypto_data_t *ciphertext,
888 crypto_data_t *plaintext, crypto_call_req_t *cr)
890 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
891 kcf_context_t *kcf_ctx;
892 kcf_provider_desc_t *pd;
894 kcf_req_params_t params;
897 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
898 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
899 return (CRYPTO_INVALID_CONTEXT);
902 /* The fast path for SW providers. */
903 if (CHECK_FASTPATH(cr, pd)) {
904 error = KCF_PROV_DECRYPT(pd, ctx, ciphertext,
906 KCF_PROV_INCRSTATS(pd, error);
908 KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_SINGLE, pd->pd_sid,
909 NULL, NULL, ciphertext, plaintext, NULL);
910 error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE);
913 /* Release the hold done in kcf_new_ctx() during init step. */
914 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
918 #if defined(_KERNEL) && defined(HAVE_SPL)
919 EXPORT_SYMBOL(crypto_cipher_init_prov);
920 EXPORT_SYMBOL(crypto_cipher_init);
921 EXPORT_SYMBOL(crypto_encrypt_prov);
922 EXPORT_SYMBOL(crypto_encrypt);
923 EXPORT_SYMBOL(crypto_encrypt_init_prov);
924 EXPORT_SYMBOL(crypto_encrypt_init);
925 EXPORT_SYMBOL(crypto_encrypt_update);
926 EXPORT_SYMBOL(crypto_encrypt_final);
927 EXPORT_SYMBOL(crypto_decrypt_prov);
928 EXPORT_SYMBOL(crypto_decrypt);
929 EXPORT_SYMBOL(crypto_decrypt_init_prov);
930 EXPORT_SYMBOL(crypto_decrypt_init);
931 EXPORT_SYMBOL(crypto_decrypt_update);
932 EXPORT_SYMBOL(crypto_decrypt_final);
933 EXPORT_SYMBOL(crypto_encrypt_single);
934 EXPORT_SYMBOL(crypto_decrypt_single);