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 https://opensource.org/licenses/CDDL-1.0.
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>
34 * Encryption and decryption routines.
43 * mech: crypto_mechanism_t pointer.
44 * mech_type is a valid value previously returned by
46 * When the mech's parameter is not NULL, its definition depends
47 * on the standard definition of the mechanism.
48 * key: pointer to a crypto_key_t structure.
49 * plaintext: The message to be encrypted
50 * ciphertext: Storage for the encrypted message. The length needed
51 * depends on the mechanism, and the plaintext's size.
52 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
53 * encryption with the 'mech' using 'key'. 'tmpl' is created by
54 * a previous call to crypto_create_ctx_template().
57 * Asynchronously submits a request for, or synchronously performs a
58 * single-part encryption of 'plaintext' with the mechanism 'mech', using
60 * When complete and successful, 'ciphertext' will contain the encrypted
62 * Relies on the KCF scheduler to pick a provider.
65 * See comment in the beginning of the file.
68 crypto_encrypt(crypto_mechanism_t
*mech
, crypto_data_t
*plaintext
,
69 crypto_key_t
*key
, crypto_ctx_template_t tmpl
, crypto_data_t
*ciphertext
)
73 kcf_provider_desc_t
*pd
;
74 kcf_ctx_template_t
*ctx_tmpl
;
75 crypto_spi_ctx_template_t spi_ctx_tmpl
= NULL
;
76 kcf_prov_tried_t
*list
= NULL
;
79 /* pd is returned held */
80 if ((pd
= kcf_get_mech_provider(mech
->cm_type
, &me
, &error
,
81 list
, CRYPTO_FG_ENCRYPT_ATOMIC
)) == NULL
) {
83 kcf_free_triedlist(list
);
87 if (((ctx_tmpl
= (kcf_ctx_template_t
*)tmpl
) != NULL
))
88 spi_ctx_tmpl
= ctx_tmpl
->ct_prov_tmpl
;
90 crypto_mechanism_t lmech
= *mech
;
91 KCF_SET_PROVIDER_MECHNUM(mech
->cm_type
, pd
, &lmech
);
92 error
= KCF_PROV_ENCRYPT_ATOMIC(pd
, &lmech
, key
,
93 plaintext
, ciphertext
, spi_ctx_tmpl
);
95 if (error
!= CRYPTO_SUCCESS
&& IS_RECOVERABLE(error
)) {
96 /* Add pd to the linked list of providers tried. */
97 if (kcf_insert_triedlist(&list
, pd
, KM_SLEEP
) != NULL
)
102 kcf_free_triedlist(list
);
104 KCF_PROV_REFRELE(pd
);
109 * crypto_decrypt_prov()
112 * pd: provider descriptor
114 * mech: crypto_mechanism_t pointer.
115 * mech_type is a valid value previously returned by
117 * When the mech's parameter is not NULL, its definition depends
118 * on the standard definition of the mechanism.
119 * key: pointer to a crypto_key_t structure.
120 * ciphertext: The message to be encrypted
121 * plaintext: Storage for the encrypted message. The length needed
122 * depends on the mechanism, and the plaintext's size.
123 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
124 * encryption with the 'mech' using 'key'. 'tmpl' is created by
125 * a previous call to crypto_create_ctx_template().
128 * Asynchronously submits a request for, or synchronously performs a
129 * single-part decryption of 'ciphertext' with the mechanism 'mech', using
131 * When complete and successful, 'plaintext' will contain the decrypted
133 * Relies on the KCF scheduler to choose a provider.
136 * See comment in the beginning of the file.
139 crypto_decrypt(crypto_mechanism_t
*mech
, crypto_data_t
*ciphertext
,
140 crypto_key_t
*key
, crypto_ctx_template_t tmpl
, crypto_data_t
*plaintext
)
143 kcf_mech_entry_t
*me
;
144 kcf_provider_desc_t
*pd
;
145 kcf_ctx_template_t
*ctx_tmpl
;
146 crypto_spi_ctx_template_t spi_ctx_tmpl
= NULL
;
147 kcf_prov_tried_t
*list
= NULL
;
150 /* pd is returned held */
151 if ((pd
= kcf_get_mech_provider(mech
->cm_type
, &me
, &error
,
152 list
, CRYPTO_FG_DECRYPT_ATOMIC
)) == NULL
) {
154 kcf_free_triedlist(list
);
158 if (((ctx_tmpl
= (kcf_ctx_template_t
*)tmpl
) != NULL
))
159 spi_ctx_tmpl
= ctx_tmpl
->ct_prov_tmpl
;
161 crypto_mechanism_t lmech
= *mech
;
162 KCF_SET_PROVIDER_MECHNUM(mech
->cm_type
, pd
, &lmech
);
164 error
= KCF_PROV_DECRYPT_ATOMIC(pd
, &lmech
, key
,
165 ciphertext
, plaintext
, spi_ctx_tmpl
);
167 if (error
!= CRYPTO_SUCCESS
&& IS_RECOVERABLE(error
)) {
168 /* Add pd to the linked list of providers tried. */
169 if (kcf_insert_triedlist(&list
, pd
, KM_SLEEP
) != NULL
)
174 kcf_free_triedlist(list
);
176 KCF_PROV_REFRELE(pd
);
181 EXPORT_SYMBOL(crypto_encrypt
);
182 EXPORT_SYMBOL(crypto_decrypt
);