Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/module/icp/api/kcf_cipher.c
48531 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
*/
26
27
#include <sys/zfs_context.h>
28
#include <sys/crypto/common.h>
29
#include <sys/crypto/impl.h>
30
#include <sys/crypto/api.h>
31
#include <sys/crypto/spi.h>
32
#include <sys/crypto/sched_impl.h>
33
34
/*
35
* Encryption and decryption routines.
36
*/
37
38
39
/*
40
* crypto_encrypt()
41
*
42
* Arguments:
43
* sid: session id
44
* mech: crypto_mechanism_t pointer.
45
* mech_type is a valid value previously returned by
46
* crypto_mech2id();
47
* When the mech's parameter is not NULL, its definition depends
48
* on the standard definition of the mechanism.
49
* key: pointer to a crypto_key_t structure.
50
* plaintext: The message to be encrypted
51
* ciphertext: Storage for the encrypted message. The length needed
52
* depends on the mechanism, and the plaintext's size.
53
* tmpl: a crypto_ctx_template_t, opaque template of a context of an
54
* encryption with the 'mech' using 'key'. 'tmpl' is created by
55
* a previous call to crypto_create_ctx_template().
56
*
57
* Description:
58
* Asynchronously submits a request for, or synchronously performs a
59
* single-part encryption of 'plaintext' with the mechanism 'mech', using
60
* the key 'key'.
61
* When complete and successful, 'ciphertext' will contain the encrypted
62
* message.
63
* Relies on the KCF scheduler to pick a provider.
64
*
65
* Returns:
66
* See comment in the beginning of the file.
67
*/
68
int
69
crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext,
70
crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *ciphertext)
71
{
72
int error;
73
kcf_mech_entry_t *me;
74
kcf_provider_desc_t *pd;
75
kcf_ctx_template_t *ctx_tmpl;
76
crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
77
kcf_prov_tried_t *list = NULL;
78
79
retry:
80
/* pd is returned held */
81
if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
82
list, CRYPTO_FG_ENCRYPT_ATOMIC)) == NULL) {
83
if (list != NULL)
84
kcf_free_triedlist(list);
85
return (error);
86
}
87
88
if (((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL))
89
spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
90
91
crypto_mechanism_t lmech = *mech;
92
KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
93
error = KCF_PROV_ENCRYPT_ATOMIC(pd, &lmech, key,
94
plaintext, ciphertext, spi_ctx_tmpl);
95
96
if (error != CRYPTO_SUCCESS && IS_RECOVERABLE(error)) {
97
/* Add pd to the linked list of providers tried. */
98
if (kcf_insert_triedlist(&list, pd, KM_SLEEP) != NULL)
99
goto retry;
100
}
101
102
if (list != NULL)
103
kcf_free_triedlist(list);
104
105
KCF_PROV_REFRELE(pd);
106
return (error);
107
}
108
109
/*
110
* crypto_decrypt_prov()
111
*
112
* Arguments:
113
* pd: provider descriptor
114
* sid: session id
115
* mech: crypto_mechanism_t pointer.
116
* mech_type is a valid value previously returned by
117
* crypto_mech2id();
118
* When the mech's parameter is not NULL, its definition depends
119
* on the standard definition of the mechanism.
120
* key: pointer to a crypto_key_t structure.
121
* ciphertext: The message to be encrypted
122
* plaintext: Storage for the encrypted message. The length needed
123
* depends on the mechanism, and the plaintext's size.
124
* tmpl: a crypto_ctx_template_t, opaque template of a context of an
125
* encryption with the 'mech' using 'key'. 'tmpl' is created by
126
* a previous call to crypto_create_ctx_template().
127
*
128
* Description:
129
* Asynchronously submits a request for, or synchronously performs a
130
* single-part decryption of 'ciphertext' with the mechanism 'mech', using
131
* the key 'key'.
132
* When complete and successful, 'plaintext' will contain the decrypted
133
* message.
134
* Relies on the KCF scheduler to choose a provider.
135
*
136
* Returns:
137
* See comment in the beginning of the file.
138
*/
139
int
140
crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext,
141
crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext)
142
{
143
int error;
144
kcf_mech_entry_t *me;
145
kcf_provider_desc_t *pd;
146
kcf_ctx_template_t *ctx_tmpl;
147
crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
148
kcf_prov_tried_t *list = NULL;
149
150
retry:
151
/* pd is returned held */
152
if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
153
list, CRYPTO_FG_DECRYPT_ATOMIC)) == NULL) {
154
if (list != NULL)
155
kcf_free_triedlist(list);
156
return (error);
157
}
158
159
if (((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL))
160
spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
161
162
crypto_mechanism_t lmech = *mech;
163
KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
164
165
error = KCF_PROV_DECRYPT_ATOMIC(pd, &lmech, key,
166
ciphertext, plaintext, spi_ctx_tmpl);
167
168
if (error != CRYPTO_SUCCESS && IS_RECOVERABLE(error)) {
169
/* Add pd to the linked list of providers tried. */
170
if (kcf_insert_triedlist(&list, pd, KM_SLEEP) != NULL)
171
goto retry;
172
}
173
174
if (list != NULL)
175
kcf_free_triedlist(list);
176
177
KCF_PROV_REFRELE(pd);
178
return (error);
179
}
180
181
#if defined(_KERNEL)
182
EXPORT_SYMBOL(crypto_encrypt);
183
EXPORT_SYMBOL(crypto_decrypt);
184
#endif
185
186