10e33efe4SConrad Meyer /*-
20e33efe4SConrad Meyer * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org>
30e33efe4SConrad Meyer * All rights reserved.
40e33efe4SConrad Meyer *
50e33efe4SConrad Meyer * Redistribution and use in source and binary forms, with or without
60e33efe4SConrad Meyer * modification, are permitted provided that the following conditions
70e33efe4SConrad Meyer * are met:
80e33efe4SConrad Meyer * 1. Redistributions of source code must retain the above copyright
90e33efe4SConrad Meyer * notice, this list of conditions and the following disclaimer.
100e33efe4SConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright
110e33efe4SConrad Meyer * notice, this list of conditions and the following disclaimer in the
120e33efe4SConrad Meyer * documentation and/or other materials provided with the distribution.
130e33efe4SConrad Meyer *
140e33efe4SConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
150e33efe4SConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
160e33efe4SConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
170e33efe4SConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
180e33efe4SConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
190e33efe4SConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
200e33efe4SConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
210e33efe4SConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
220e33efe4SConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
230e33efe4SConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
240e33efe4SConrad Meyer * SUCH DAMAGE.
250e33efe4SConrad Meyer */
260e33efe4SConrad Meyer
270e33efe4SConrad Meyer #include <sys/param.h>
280e33efe4SConrad Meyer #include <sys/bus.h>
290e33efe4SConrad Meyer #include <sys/kernel.h>
300e33efe4SConrad Meyer #include <sys/kobj.h>
310e33efe4SConrad Meyer #include <sys/malloc.h>
32e2e050c8SConrad Meyer #include <sys/module.h>
33e2e050c8SConrad Meyer #include <sys/mutex.h>
340e33efe4SConrad Meyer #include <sys/smp.h>
350e33efe4SConrad Meyer
360e33efe4SConrad Meyer #include <blake2.h>
370e33efe4SConrad Meyer
380e33efe4SConrad Meyer #include <opencrypto/cryptodev.h>
390e33efe4SConrad Meyer #include <cryptodev_if.h>
400e33efe4SConrad Meyer
410e33efe4SConrad Meyer #include <machine/fpu.h>
420e33efe4SConrad Meyer
430e33efe4SConrad Meyer struct blake2_session {
440e33efe4SConrad Meyer size_t mlen;
450e33efe4SConrad Meyer };
460e33efe4SConrad Meyer CTASSERT((size_t)BLAKE2B_KEYBYTES > (size_t)BLAKE2S_KEYBYTES);
470e33efe4SConrad Meyer
480e33efe4SConrad Meyer struct blake2_softc {
490e33efe4SConrad Meyer int32_t cid;
500e33efe4SConrad Meyer };
510e33efe4SConrad Meyer
520e33efe4SConrad Meyer static int blake2_cipher_setup(struct blake2_session *ses,
53c0341432SJohn Baldwin const struct crypto_session_params *csp);
540e33efe4SConrad Meyer static int blake2_cipher_process(struct blake2_session *ses,
550e33efe4SConrad Meyer struct cryptop *crp);
560e33efe4SConrad Meyer
570e33efe4SConrad Meyer MALLOC_DEFINE(M_BLAKE2, "blake2_data", "Blake2 Data");
580e33efe4SConrad Meyer
590e33efe4SConrad Meyer static void
blake2_identify(driver_t * drv,device_t parent)600e33efe4SConrad Meyer blake2_identify(driver_t *drv, device_t parent)
610e33efe4SConrad Meyer {
620e33efe4SConrad Meyer
630e33efe4SConrad Meyer /* NB: order 10 is so we get attached after h/w devices */
640e33efe4SConrad Meyer if (device_find_child(parent, "blaketwo", -1) == NULL &&
650e33efe4SConrad Meyer BUS_ADD_CHILD(parent, 10, "blaketwo", -1) == 0)
660e33efe4SConrad Meyer panic("blaketwo: could not attach");
670e33efe4SConrad Meyer }
680e33efe4SConrad Meyer
690e33efe4SConrad Meyer static int
blake2_probe(device_t dev)700e33efe4SConrad Meyer blake2_probe(device_t dev)
710e33efe4SConrad Meyer {
720e33efe4SConrad Meyer device_set_desc(dev, "Blake2");
730e33efe4SConrad Meyer return (0);
740e33efe4SConrad Meyer }
750e33efe4SConrad Meyer
760e33efe4SConrad Meyer static int
blake2_attach(device_t dev)770e33efe4SConrad Meyer blake2_attach(device_t dev)
780e33efe4SConrad Meyer {
790e33efe4SConrad Meyer struct blake2_softc *sc;
800e33efe4SConrad Meyer
810e33efe4SConrad Meyer sc = device_get_softc(dev);
820e33efe4SConrad Meyer
831b0909d5SConrad Meyer sc->cid = crypto_get_driverid(dev, sizeof(struct blake2_session),
84a3d565a1SJohn Baldwin CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC |
85a3d565a1SJohn Baldwin CRYPTOCAP_F_ACCEL_SOFTWARE);
860e33efe4SConrad Meyer if (sc->cid < 0) {
870e33efe4SConrad Meyer device_printf(dev, "Could not get crypto driver id.\n");
880e33efe4SConrad Meyer return (ENOMEM);
890e33efe4SConrad Meyer }
900e33efe4SConrad Meyer
910e33efe4SConrad Meyer return (0);
920e33efe4SConrad Meyer }
930e33efe4SConrad Meyer
940e33efe4SConrad Meyer static int
blake2_detach(device_t dev)950e33efe4SConrad Meyer blake2_detach(device_t dev)
960e33efe4SConrad Meyer {
970e33efe4SConrad Meyer struct blake2_softc *sc;
980e33efe4SConrad Meyer
990e33efe4SConrad Meyer sc = device_get_softc(dev);
1000e33efe4SConrad Meyer
1010e33efe4SConrad Meyer crypto_unregister_all(sc->cid);
1020e33efe4SConrad Meyer
1030e33efe4SConrad Meyer return (0);
1040e33efe4SConrad Meyer }
1050e33efe4SConrad Meyer
1060e33efe4SConrad Meyer static int
blake2_probesession(device_t dev,const struct crypto_session_params * csp)107c0341432SJohn Baldwin blake2_probesession(device_t dev, const struct crypto_session_params *csp)
108c0341432SJohn Baldwin {
109c0341432SJohn Baldwin
110c0341432SJohn Baldwin if (csp->csp_flags != 0)
111c0341432SJohn Baldwin return (EINVAL);
112c0341432SJohn Baldwin switch (csp->csp_mode) {
113c0341432SJohn Baldwin case CSP_MODE_DIGEST:
114c0341432SJohn Baldwin switch (csp->csp_auth_alg) {
115c0341432SJohn Baldwin case CRYPTO_BLAKE2B:
116c0341432SJohn Baldwin case CRYPTO_BLAKE2S:
117c0341432SJohn Baldwin break;
118c0341432SJohn Baldwin default:
119c0341432SJohn Baldwin return (EINVAL);
120c0341432SJohn Baldwin }
121c0341432SJohn Baldwin break;
122c0341432SJohn Baldwin default:
123c0341432SJohn Baldwin return (EINVAL);
124c0341432SJohn Baldwin }
125c0341432SJohn Baldwin return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
126c0341432SJohn Baldwin }
127c0341432SJohn Baldwin
128c0341432SJohn Baldwin static int
blake2_newsession(device_t dev,crypto_session_t cses,const struct crypto_session_params * csp)129c0341432SJohn Baldwin blake2_newsession(device_t dev, crypto_session_t cses,
130c0341432SJohn Baldwin const struct crypto_session_params *csp)
1310e33efe4SConrad Meyer {
1320e33efe4SConrad Meyer struct blake2_session *ses;
1330e33efe4SConrad Meyer int error;
1340e33efe4SConrad Meyer
1351b0909d5SConrad Meyer ses = crypto_get_driver_session(cses);
1360e33efe4SConrad Meyer
137c0341432SJohn Baldwin error = blake2_cipher_setup(ses, csp);
1380e33efe4SConrad Meyer if (error != 0) {
1390e33efe4SConrad Meyer CRYPTDEB("setup failed");
1400e33efe4SConrad Meyer return (error);
1410e33efe4SConrad Meyer }
1420e33efe4SConrad Meyer
1430e33efe4SConrad Meyer return (0);
1440e33efe4SConrad Meyer }
1450e33efe4SConrad Meyer
1460e33efe4SConrad Meyer static int
blake2_process(device_t dev,struct cryptop * crp,int hint __unused)1470e33efe4SConrad Meyer blake2_process(device_t dev, struct cryptop *crp, int hint __unused)
1480e33efe4SConrad Meyer {
1490e33efe4SConrad Meyer struct blake2_session *ses;
1500e33efe4SConrad Meyer int error;
1510e33efe4SConrad Meyer
1521b0909d5SConrad Meyer ses = crypto_get_driver_session(crp->crp_session);
1530e33efe4SConrad Meyer error = blake2_cipher_process(ses, crp);
1540e33efe4SConrad Meyer
1550e33efe4SConrad Meyer crp->crp_etype = error;
1560e33efe4SConrad Meyer crypto_done(crp);
157c0341432SJohn Baldwin return (0);
1580e33efe4SConrad Meyer }
1590e33efe4SConrad Meyer
1600e33efe4SConrad Meyer static device_method_t blake2_methods[] = {
1610e33efe4SConrad Meyer DEVMETHOD(device_identify, blake2_identify),
1620e33efe4SConrad Meyer DEVMETHOD(device_probe, blake2_probe),
1630e33efe4SConrad Meyer DEVMETHOD(device_attach, blake2_attach),
1640e33efe4SConrad Meyer DEVMETHOD(device_detach, blake2_detach),
1650e33efe4SConrad Meyer
166c0341432SJohn Baldwin DEVMETHOD(cryptodev_probesession, blake2_probesession),
1670e33efe4SConrad Meyer DEVMETHOD(cryptodev_newsession, blake2_newsession),
1680e33efe4SConrad Meyer DEVMETHOD(cryptodev_process, blake2_process),
1690e33efe4SConrad Meyer
1700e33efe4SConrad Meyer DEVMETHOD_END
1710e33efe4SConrad Meyer };
1720e33efe4SConrad Meyer
1730e33efe4SConrad Meyer static driver_t blake2_driver = {
1740e33efe4SConrad Meyer "blaketwo",
1750e33efe4SConrad Meyer blake2_methods,
1760e33efe4SConrad Meyer sizeof(struct blake2_softc),
1770e33efe4SConrad Meyer };
1780e33efe4SConrad Meyer
179ab050b2bSJohn Baldwin DRIVER_MODULE(blake2, nexus, blake2_driver, 0, 0);
1800e33efe4SConrad Meyer MODULE_VERSION(blake2, 1);
1810e33efe4SConrad Meyer MODULE_DEPEND(blake2, crypto, 1, 1, 1);
1820e33efe4SConrad Meyer
183c0341432SJohn Baldwin static bool
blake2_check_klen(const struct crypto_session_params * csp,unsigned klen)184c0341432SJohn Baldwin blake2_check_klen(const struct crypto_session_params *csp, unsigned klen)
1850e33efe4SConrad Meyer {
186c0341432SJohn Baldwin
187c0341432SJohn Baldwin if (csp->csp_auth_alg == CRYPTO_BLAKE2S)
188c0341432SJohn Baldwin return (klen <= BLAKE2S_KEYBYTES);
189c0341432SJohn Baldwin else
190c0341432SJohn Baldwin return (klen <= BLAKE2B_KEYBYTES);
191c0341432SJohn Baldwin }
192c0341432SJohn Baldwin
193c0341432SJohn Baldwin static int
blake2_cipher_setup(struct blake2_session * ses,const struct crypto_session_params * csp)194c0341432SJohn Baldwin blake2_cipher_setup(struct blake2_session *ses,
195c0341432SJohn Baldwin const struct crypto_session_params *csp)
196c0341432SJohn Baldwin {
197c0341432SJohn Baldwin int hashlen;
1980e33efe4SConrad Meyer
1990e33efe4SConrad Meyer CTASSERT((size_t)BLAKE2S_OUTBYTES <= (size_t)BLAKE2B_OUTBYTES);
2000e33efe4SConrad Meyer
201c0341432SJohn Baldwin if (!blake2_check_klen(csp, csp->csp_auth_klen))
2020e33efe4SConrad Meyer return (EINVAL);
2030e33efe4SConrad Meyer
204c0341432SJohn Baldwin if (csp->csp_auth_mlen < 0)
205c0341432SJohn Baldwin return (EINVAL);
206c0341432SJohn Baldwin
207c0341432SJohn Baldwin switch (csp->csp_auth_alg) {
2080e33efe4SConrad Meyer case CRYPTO_BLAKE2S:
209c0341432SJohn Baldwin hashlen = BLAKE2S_OUTBYTES;
210c0341432SJohn Baldwin break;
2110e33efe4SConrad Meyer case CRYPTO_BLAKE2B:
212c0341432SJohn Baldwin hashlen = BLAKE2B_OUTBYTES;
213c0341432SJohn Baldwin break;
214c0341432SJohn Baldwin default:
215c0341432SJohn Baldwin return (EINVAL);
216c0341432SJohn Baldwin }
217c0341432SJohn Baldwin
218c0341432SJohn Baldwin if (csp->csp_auth_mlen > hashlen)
2190e33efe4SConrad Meyer return (EINVAL);
2200e33efe4SConrad Meyer
221c0341432SJohn Baldwin if (csp->csp_auth_mlen == 0)
222c0341432SJohn Baldwin ses->mlen = hashlen;
223c0341432SJohn Baldwin else
224c0341432SJohn Baldwin ses->mlen = csp->csp_auth_mlen;
2250e33efe4SConrad Meyer return (0);
2260e33efe4SConrad Meyer }
2270e33efe4SConrad Meyer
2280e33efe4SConrad Meyer static int
blake2b_applicator(void * state,const void * buf,u_int len)2299b6b2f86SJohn Baldwin blake2b_applicator(void *state, const void *buf, u_int len)
2300e33efe4SConrad Meyer {
2310e33efe4SConrad Meyer int rc;
2320e33efe4SConrad Meyer
2330e33efe4SConrad Meyer rc = blake2b_update(state, buf, len);
2340e33efe4SConrad Meyer if (rc != 0)
2350e33efe4SConrad Meyer return (EINVAL);
2360e33efe4SConrad Meyer return (0);
2370e33efe4SConrad Meyer }
2380e33efe4SConrad Meyer
2390e33efe4SConrad Meyer static int
blake2s_applicator(void * state,const void * buf,u_int len)2409b6b2f86SJohn Baldwin blake2s_applicator(void *state, const void *buf, u_int len)
2410e33efe4SConrad Meyer {
2420e33efe4SConrad Meyer int rc;
2430e33efe4SConrad Meyer
2440e33efe4SConrad Meyer rc = blake2s_update(state, buf, len);
2450e33efe4SConrad Meyer if (rc != 0)
2460e33efe4SConrad Meyer return (EINVAL);
2470e33efe4SConrad Meyer return (0);
2480e33efe4SConrad Meyer }
2490e33efe4SConrad Meyer
2500e33efe4SConrad Meyer static int
blake2_cipher_process(struct blake2_session * ses,struct cryptop * crp)2510e33efe4SConrad Meyer blake2_cipher_process(struct blake2_session *ses, struct cryptop *crp)
2520e33efe4SConrad Meyer {
2530e33efe4SConrad Meyer union {
2540e33efe4SConrad Meyer blake2b_state sb;
2550e33efe4SConrad Meyer blake2s_state ss;
2560e33efe4SConrad Meyer } bctx;
257c0341432SJohn Baldwin char res[BLAKE2B_OUTBYTES], res2[BLAKE2B_OUTBYTES];
258c0341432SJohn Baldwin const struct crypto_session_params *csp;
259c0341432SJohn Baldwin const void *key;
2600e33efe4SConrad Meyer int error, rc;
261c0341432SJohn Baldwin unsigned klen;
2620e33efe4SConrad Meyer
263c0341432SJohn Baldwin csp = crypto_get_params(crp->crp_session);
264c0341432SJohn Baldwin if (crp->crp_auth_key != NULL)
265c0341432SJohn Baldwin key = crp->crp_auth_key;
266c0341432SJohn Baldwin else
267c0341432SJohn Baldwin key = csp->csp_auth_key;
268c0341432SJohn Baldwin klen = csp->csp_auth_klen;
269*3e912bdcSJohn Baldwin
270*3e912bdcSJohn Baldwin fpu_kern_enter(curthread, NULL, FPU_KERN_NORMAL | FPU_KERN_NOCTX);
271*3e912bdcSJohn Baldwin
272c0341432SJohn Baldwin switch (csp->csp_auth_alg) {
2730e33efe4SConrad Meyer case CRYPTO_BLAKE2B:
274c0341432SJohn Baldwin if (klen > 0)
275c0341432SJohn Baldwin rc = blake2b_init_key(&bctx.sb, ses->mlen, key, klen);
2760e33efe4SConrad Meyer else
277c0341432SJohn Baldwin rc = blake2b_init(&bctx.sb, ses->mlen);
278*3e912bdcSJohn Baldwin if (rc != 0) {
279*3e912bdcSJohn Baldwin error = EINVAL;
280*3e912bdcSJohn Baldwin break;
281*3e912bdcSJohn Baldwin }
282c0341432SJohn Baldwin error = crypto_apply(crp, crp->crp_payload_start,
283c0341432SJohn Baldwin crp->crp_payload_length, blake2b_applicator, &bctx.sb);
2840e33efe4SConrad Meyer if (error != 0)
285*3e912bdcSJohn Baldwin break;
286c0341432SJohn Baldwin rc = blake2b_final(&bctx.sb, res, ses->mlen);
287*3e912bdcSJohn Baldwin if (rc != 0)
2880e33efe4SConrad Meyer error = EINVAL;
2890e33efe4SConrad Meyer break;
2900e33efe4SConrad Meyer case CRYPTO_BLAKE2S:
291c0341432SJohn Baldwin if (klen > 0)
292c0341432SJohn Baldwin rc = blake2s_init_key(&bctx.ss, ses->mlen, key, klen);
2930e33efe4SConrad Meyer else
294c0341432SJohn Baldwin rc = blake2s_init(&bctx.ss, ses->mlen);
295*3e912bdcSJohn Baldwin if (rc != 0) {
296*3e912bdcSJohn Baldwin error = EINVAL;
297*3e912bdcSJohn Baldwin break;
298*3e912bdcSJohn Baldwin }
299c0341432SJohn Baldwin error = crypto_apply(crp, crp->crp_payload_start,
300c0341432SJohn Baldwin crp->crp_payload_length, blake2s_applicator, &bctx.ss);
3010e33efe4SConrad Meyer if (error != 0)
302*3e912bdcSJohn Baldwin break;
303c0341432SJohn Baldwin rc = blake2s_final(&bctx.ss, res, ses->mlen);
304*3e912bdcSJohn Baldwin if (rc != 0)
3050e33efe4SConrad Meyer error = EINVAL;
3060e33efe4SConrad Meyer break;
3070e33efe4SConrad Meyer default:
308*3e912bdcSJohn Baldwin __assert_unreachable();
3090e33efe4SConrad Meyer }
3100e33efe4SConrad Meyer
311*3e912bdcSJohn Baldwin fpu_kern_leave(curthread, NULL);
312*3e912bdcSJohn Baldwin
313*3e912bdcSJohn Baldwin if (error != 0)
314*3e912bdcSJohn Baldwin return (error);
315*3e912bdcSJohn Baldwin
316c0341432SJohn Baldwin if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
317c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, ses->mlen, res2);
318c0341432SJohn Baldwin if (timingsafe_bcmp(res, res2, ses->mlen) != 0)
319*3e912bdcSJohn Baldwin error = EBADMSG;
320c0341432SJohn Baldwin } else
321c0341432SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, ses->mlen, res);
3220e33efe4SConrad Meyer
3230e33efe4SConrad Meyer return (error);
3240e33efe4SConrad Meyer }
325