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
);