2 * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/param.h>
29 #include <sys/kernel.h>
31 #include <sys/malloc.h>
32 #include <sys/module.h>
33 #include <sys/mutex.h>
38 #include <opencrypto/cryptodev.h>
39 #include <cryptodev_if.h>
41 #include <machine/fpu.h>
43 struct blake2_session
{
46 CTASSERT((size_t)BLAKE2B_KEYBYTES
> (size_t)BLAKE2S_KEYBYTES
);
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
,
57 MALLOC_DEFINE(M_BLAKE2
, "blake2_data", "Blake2 Data");
60 blake2_identify(driver_t
*drv
, device_t parent
)
63 /* NB: order 10 is so we get attached after h/w devices */
64 if (device_find_child(parent
, "blaketwo", -1) == NULL
&&
65 BUS_ADD_CHILD(parent
, 10, "blaketwo", -1) == 0)
66 panic("blaketwo: could not attach");
70 blake2_probe(device_t dev
)
72 device_set_desc(dev
, "Blake2");
77 blake2_attach(device_t dev
)
79 struct blake2_softc
*sc
;
81 sc
= device_get_softc(dev
);
83 sc
->cid
= crypto_get_driverid(dev
, sizeof(struct blake2_session
),
84 CRYPTOCAP_F_SOFTWARE
| CRYPTOCAP_F_SYNC
|
85 CRYPTOCAP_F_ACCEL_SOFTWARE
);
87 device_printf(dev
, "Could not get crypto driver id.\n");
95 blake2_detach(device_t dev
)
97 struct blake2_softc
*sc
;
99 sc
= device_get_softc(dev
);
101 crypto_unregister_all(sc
->cid
);
107 blake2_probesession(device_t dev
, const struct crypto_session_params
*csp
)
110 if (csp
->csp_flags
!= 0)
112 switch (csp
->csp_mode
) {
113 case CSP_MODE_DIGEST
:
114 switch (csp
->csp_auth_alg
) {
125 return (CRYPTODEV_PROBE_ACCEL_SOFTWARE
);
129 blake2_newsession(device_t dev
, crypto_session_t cses
,
130 const struct crypto_session_params
*csp
)
132 struct blake2_session
*ses
;
135 ses
= crypto_get_driver_session(cses
);
137 error
= blake2_cipher_setup(ses
, csp
);
139 CRYPTDEB("setup failed");
147 blake2_process(device_t dev
, struct cryptop
*crp
, int hint __unused
)
149 struct blake2_session
*ses
;
152 ses
= crypto_get_driver_session(crp
->crp_session
);
153 error
= blake2_cipher_process(ses
, crp
);
155 crp
->crp_etype
= error
;
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
),
166 DEVMETHOD(cryptodev_probesession
, blake2_probesession
),
167 DEVMETHOD(cryptodev_newsession
, blake2_newsession
),
168 DEVMETHOD(cryptodev_process
, blake2_process
),
173 static driver_t blake2_driver
= {
176 sizeof(struct blake2_softc
),
179 DRIVER_MODULE(blake2
, nexus
, blake2_driver
, 0, 0);
180 MODULE_VERSION(blake2
, 1);
181 MODULE_DEPEND(blake2
, crypto
, 1, 1, 1);
184 blake2_check_klen(const struct crypto_session_params
*csp
, unsigned klen
)
187 if (csp
->csp_auth_alg
== CRYPTO_BLAKE2S
)
188 return (klen
<= BLAKE2S_KEYBYTES
);
190 return (klen
<= BLAKE2B_KEYBYTES
);
194 blake2_cipher_setup(struct blake2_session
*ses
,
195 const struct crypto_session_params
*csp
)
199 CTASSERT((size_t)BLAKE2S_OUTBYTES
<= (size_t)BLAKE2B_OUTBYTES
);
201 if (!blake2_check_klen(csp
, csp
->csp_auth_klen
))
204 if (csp
->csp_auth_mlen
< 0)
207 switch (csp
->csp_auth_alg
) {
209 hashlen
= BLAKE2S_OUTBYTES
;
212 hashlen
= BLAKE2B_OUTBYTES
;
218 if (csp
->csp_auth_mlen
> hashlen
)
221 if (csp
->csp_auth_mlen
== 0)
224 ses
->mlen
= csp
->csp_auth_mlen
;
229 blake2b_applicator(void *state
, const void *buf
, u_int len
)
233 rc
= blake2b_update(state
, buf
, len
);
240 blake2s_applicator(void *state
, const void *buf
, u_int len
)
244 rc
= blake2s_update(state
, buf
, len
);
251 blake2_cipher_process(struct blake2_session
*ses
, struct cryptop
*crp
)
257 char res
[BLAKE2B_OUTBYTES
], res2
[BLAKE2B_OUTBYTES
];
258 const struct crypto_session_params
*csp
;
263 csp
= crypto_get_params(crp
->crp_session
);
264 if (crp
->crp_auth_key
!= NULL
)
265 key
= crp
->crp_auth_key
;
267 key
= csp
->csp_auth_key
;
268 klen
= csp
->csp_auth_klen
;
270 fpu_kern_enter(curthread
, NULL
, FPU_KERN_NORMAL
| FPU_KERN_NOCTX
);
272 switch (csp
->csp_auth_alg
) {
275 rc
= blake2b_init_key(&bctx
.sb
, ses
->mlen
, key
, klen
);
277 rc
= blake2b_init(&bctx
.sb
, ses
->mlen
);
282 error
= crypto_apply(crp
, crp
->crp_payload_start
,
283 crp
->crp_payload_length
, blake2b_applicator
, &bctx
.sb
);
286 rc
= blake2b_final(&bctx
.sb
, res
, ses
->mlen
);
292 rc
= blake2s_init_key(&bctx
.ss
, ses
->mlen
, key
, klen
);
294 rc
= blake2s_init(&bctx
.ss
, ses
->mlen
);
299 error
= crypto_apply(crp
, crp
->crp_payload_start
,
300 crp
->crp_payload_length
, blake2s_applicator
, &bctx
.ss
);
303 rc
= blake2s_final(&bctx
.ss
, res
, ses
->mlen
);
308 __assert_unreachable();
311 fpu_kern_leave(curthread
, NULL
);
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)
321 crypto_copyback(crp
, crp
->crp_digest_start
, ses
->mlen
, res
);