xref: /freebsd-src/sys/crypto/blake2/blake2_cryptodev.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
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