Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/crypto/blake2/blake2_cryptodev.c
39536 views
1
/*-
2
* Copyright (c) 2018 Conrad Meyer <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
#include <sys/param.h>
28
#include <sys/bus.h>
29
#include <sys/kernel.h>
30
#include <sys/kobj.h>
31
#include <sys/malloc.h>
32
#include <sys/module.h>
33
#include <sys/mutex.h>
34
#include <sys/smp.h>
35
36
#include <blake2.h>
37
38
#include <opencrypto/cryptodev.h>
39
#include <cryptodev_if.h>
40
41
#include <machine/fpu.h>
42
43
struct blake2_session {
44
size_t mlen;
45
};
46
CTASSERT((size_t)BLAKE2B_KEYBYTES > (size_t)BLAKE2S_KEYBYTES);
47
48
struct blake2_softc {
49
int32_t cid;
50
};
51
52
static int blake2_cipher_setup(struct blake2_session *ses,
53
const struct crypto_session_params *csp);
54
static int blake2_cipher_process(struct blake2_session *ses,
55
struct cryptop *crp);
56
57
MALLOC_DEFINE(M_BLAKE2, "blake2_data", "Blake2 Data");
58
59
static void
60
blake2_identify(driver_t *drv, device_t parent)
61
{
62
63
/* NB: order 10 is so we get attached after h/w devices */
64
if (device_find_child(parent, "blaketwo", DEVICE_UNIT_ANY) == NULL &&
65
BUS_ADD_CHILD(parent, 10, "blaketwo", DEVICE_UNIT_ANY) == 0)
66
panic("blaketwo: could not attach");
67
}
68
69
static int
70
blake2_probe(device_t dev)
71
{
72
device_set_desc(dev, "Blake2");
73
return (0);
74
}
75
76
static int
77
blake2_attach(device_t dev)
78
{
79
struct blake2_softc *sc;
80
81
sc = device_get_softc(dev);
82
83
sc->cid = crypto_get_driverid(dev, sizeof(struct blake2_session),
84
CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC |
85
CRYPTOCAP_F_ACCEL_SOFTWARE);
86
if (sc->cid < 0) {
87
device_printf(dev, "Could not get crypto driver id.\n");
88
return (ENOMEM);
89
}
90
91
return (0);
92
}
93
94
static int
95
blake2_detach(device_t dev)
96
{
97
struct blake2_softc *sc;
98
99
sc = device_get_softc(dev);
100
101
crypto_unregister_all(sc->cid);
102
103
return (0);
104
}
105
106
static int
107
blake2_probesession(device_t dev, const struct crypto_session_params *csp)
108
{
109
110
if (csp->csp_flags != 0)
111
return (EINVAL);
112
switch (csp->csp_mode) {
113
case CSP_MODE_DIGEST:
114
switch (csp->csp_auth_alg) {
115
case CRYPTO_BLAKE2B:
116
case CRYPTO_BLAKE2S:
117
break;
118
default:
119
return (EINVAL);
120
}
121
break;
122
default:
123
return (EINVAL);
124
}
125
return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
126
}
127
128
static int
129
blake2_newsession(device_t dev, crypto_session_t cses,
130
const struct crypto_session_params *csp)
131
{
132
struct blake2_session *ses;
133
int error;
134
135
ses = crypto_get_driver_session(cses);
136
137
error = blake2_cipher_setup(ses, csp);
138
if (error != 0) {
139
CRYPTDEB("setup failed");
140
return (error);
141
}
142
143
return (0);
144
}
145
146
static int
147
blake2_process(device_t dev, struct cryptop *crp, int hint __unused)
148
{
149
struct blake2_session *ses;
150
int error;
151
152
ses = crypto_get_driver_session(crp->crp_session);
153
error = blake2_cipher_process(ses, crp);
154
155
crp->crp_etype = error;
156
crypto_done(crp);
157
return (0);
158
}
159
160
static device_method_t blake2_methods[] = {
161
DEVMETHOD(device_identify, blake2_identify),
162
DEVMETHOD(device_probe, blake2_probe),
163
DEVMETHOD(device_attach, blake2_attach),
164
DEVMETHOD(device_detach, blake2_detach),
165
166
DEVMETHOD(cryptodev_probesession, blake2_probesession),
167
DEVMETHOD(cryptodev_newsession, blake2_newsession),
168
DEVMETHOD(cryptodev_process, blake2_process),
169
170
DEVMETHOD_END
171
};
172
173
static driver_t blake2_driver = {
174
"blaketwo",
175
blake2_methods,
176
sizeof(struct blake2_softc),
177
};
178
179
DRIVER_MODULE(blake2, nexus, blake2_driver, 0, 0);
180
MODULE_VERSION(blake2, 1);
181
MODULE_DEPEND(blake2, crypto, 1, 1, 1);
182
183
static bool
184
blake2_check_klen(const struct crypto_session_params *csp, unsigned klen)
185
{
186
187
if (csp->csp_auth_alg == CRYPTO_BLAKE2S)
188
return (klen <= BLAKE2S_KEYBYTES);
189
else
190
return (klen <= BLAKE2B_KEYBYTES);
191
}
192
193
static int
194
blake2_cipher_setup(struct blake2_session *ses,
195
const struct crypto_session_params *csp)
196
{
197
int hashlen;
198
199
CTASSERT((size_t)BLAKE2S_OUTBYTES <= (size_t)BLAKE2B_OUTBYTES);
200
201
if (!blake2_check_klen(csp, csp->csp_auth_klen))
202
return (EINVAL);
203
204
if (csp->csp_auth_mlen < 0)
205
return (EINVAL);
206
207
switch (csp->csp_auth_alg) {
208
case CRYPTO_BLAKE2S:
209
hashlen = BLAKE2S_OUTBYTES;
210
break;
211
case CRYPTO_BLAKE2B:
212
hashlen = BLAKE2B_OUTBYTES;
213
break;
214
default:
215
return (EINVAL);
216
}
217
218
if (csp->csp_auth_mlen > hashlen)
219
return (EINVAL);
220
221
if (csp->csp_auth_mlen == 0)
222
ses->mlen = hashlen;
223
else
224
ses->mlen = csp->csp_auth_mlen;
225
return (0);
226
}
227
228
static int
229
blake2b_applicator(void *state, const void *buf, u_int len)
230
{
231
int rc;
232
233
rc = blake2b_update(state, buf, len);
234
if (rc != 0)
235
return (EINVAL);
236
return (0);
237
}
238
239
static int
240
blake2s_applicator(void *state, const void *buf, u_int len)
241
{
242
int rc;
243
244
rc = blake2s_update(state, buf, len);
245
if (rc != 0)
246
return (EINVAL);
247
return (0);
248
}
249
250
static int
251
blake2_cipher_process(struct blake2_session *ses, struct cryptop *crp)
252
{
253
union {
254
blake2b_state sb;
255
blake2s_state ss;
256
} bctx;
257
char res[BLAKE2B_OUTBYTES], res2[BLAKE2B_OUTBYTES];
258
const struct crypto_session_params *csp;
259
const void *key;
260
int error, rc;
261
unsigned klen;
262
263
csp = crypto_get_params(crp->crp_session);
264
if (crp->crp_auth_key != NULL)
265
key = crp->crp_auth_key;
266
else
267
key = csp->csp_auth_key;
268
klen = csp->csp_auth_klen;
269
270
fpu_kern_enter(curthread, NULL, FPU_KERN_NORMAL | FPU_KERN_NOCTX);
271
272
switch (csp->csp_auth_alg) {
273
case CRYPTO_BLAKE2B:
274
if (klen > 0)
275
rc = blake2b_init_key(&bctx.sb, ses->mlen, key, klen);
276
else
277
rc = blake2b_init(&bctx.sb, ses->mlen);
278
if (rc != 0) {
279
error = EINVAL;
280
break;
281
}
282
error = crypto_apply(crp, crp->crp_payload_start,
283
crp->crp_payload_length, blake2b_applicator, &bctx.sb);
284
if (error != 0)
285
break;
286
rc = blake2b_final(&bctx.sb, res, ses->mlen);
287
if (rc != 0)
288
error = EINVAL;
289
break;
290
case CRYPTO_BLAKE2S:
291
if (klen > 0)
292
rc = blake2s_init_key(&bctx.ss, ses->mlen, key, klen);
293
else
294
rc = blake2s_init(&bctx.ss, ses->mlen);
295
if (rc != 0) {
296
error = EINVAL;
297
break;
298
}
299
error = crypto_apply(crp, crp->crp_payload_start,
300
crp->crp_payload_length, blake2s_applicator, &bctx.ss);
301
if (error != 0)
302
break;
303
rc = blake2s_final(&bctx.ss, res, ses->mlen);
304
if (rc != 0)
305
error = EINVAL;
306
break;
307
default:
308
__assert_unreachable();
309
}
310
311
fpu_kern_leave(curthread, NULL);
312
313
if (error != 0)
314
return (error);
315
316
if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
317
crypto_copydata(crp, crp->crp_digest_start, ses->mlen, res2);
318
if (timingsafe_bcmp(res, res2, ses->mlen) != 0)
319
error = EBADMSG;
320
} else
321
crypto_copyback(crp, crp->crp_digest_start, ses->mlen, res);
322
323
return (error);
324
}
325
326