xref: /freebsd/sys/crypto/openssl/ossl.c (revision 92aecd1e6fac47ffc893f628c1fe289568bb19cb)
1fd86ae68SMitchell Horne /*-
2fd86ae68SMitchell Horne  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3fd86ae68SMitchell Horne  *
4ba610be9SJohn Baldwin  * Copyright (c) 2020 Netflix, Inc
5ba610be9SJohn Baldwin  *
6ba610be9SJohn Baldwin  * Redistribution and use in source and binary forms, with or without
7ba610be9SJohn Baldwin  * modification, are permitted provided that the following conditions
8ba610be9SJohn Baldwin  * are met:
9ba610be9SJohn Baldwin  * 1. Redistributions of source code must retain the above copyright
10ba610be9SJohn Baldwin  *    notice, this list of conditions and the following disclaimer,
11ba610be9SJohn Baldwin  *    without modification.
12ba610be9SJohn Baldwin  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13ba610be9SJohn Baldwin  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
14ba610be9SJohn Baldwin  *    redistribution must be conditioned upon including a substantially
15ba610be9SJohn Baldwin  *    similar Disclaimer requirement for further binary redistribution.
16ba610be9SJohn Baldwin  *
17ba610be9SJohn Baldwin  * NO WARRANTY
18ba610be9SJohn Baldwin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19ba610be9SJohn Baldwin  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20ba610be9SJohn Baldwin  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
21ba610be9SJohn Baldwin  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22ba610be9SJohn Baldwin  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
23ba610be9SJohn Baldwin  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24ba610be9SJohn Baldwin  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25ba610be9SJohn Baldwin  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26ba610be9SJohn Baldwin  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27ba610be9SJohn Baldwin  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28ba610be9SJohn Baldwin  * THE POSSIBILITY OF SUCH DAMAGES.
29ba610be9SJohn Baldwin  */
30ba610be9SJohn Baldwin 
31ba610be9SJohn Baldwin /*
32ba610be9SJohn Baldwin  * A driver for the OpenCrypto framework which uses assembly routines
33ba610be9SJohn Baldwin  * from OpenSSL.
34ba610be9SJohn Baldwin  */
35ba610be9SJohn Baldwin 
36ba610be9SJohn Baldwin #include <sys/cdefs.h>
37ba610be9SJohn Baldwin __FBSDID("$FreeBSD$");
38ba610be9SJohn Baldwin 
39ba610be9SJohn Baldwin #include <sys/types.h>
40ba610be9SJohn Baldwin #include <sys/bus.h>
41ba610be9SJohn Baldwin #include <sys/kernel.h>
42ba610be9SJohn Baldwin #include <sys/malloc.h>
43ba610be9SJohn Baldwin #include <sys/module.h>
44fd86ae68SMitchell Horne 
45ba610be9SJohn Baldwin #include <machine/fpu.h>
46ba610be9SJohn Baldwin 
47ba610be9SJohn Baldwin #include <opencrypto/cryptodev.h>
48ba610be9SJohn Baldwin #include <opencrypto/xform_auth.h>
49ba610be9SJohn Baldwin 
50ba610be9SJohn Baldwin #include <crypto/openssl/ossl.h>
51*92aecd1eSJohn Baldwin #include <crypto/openssl/ossl_chacha.h>
52ba610be9SJohn Baldwin 
53ba610be9SJohn Baldwin #include "cryptodev_if.h"
54ba610be9SJohn Baldwin 
55ba610be9SJohn Baldwin struct ossl_softc {
56ba610be9SJohn Baldwin 	int32_t sc_cid;
57ba610be9SJohn Baldwin };
58ba610be9SJohn Baldwin 
59ba610be9SJohn Baldwin struct ossl_session_hash {
60ba610be9SJohn Baldwin 	struct ossl_hash_context ictx;
61ba610be9SJohn Baldwin 	struct ossl_hash_context octx;
62ba610be9SJohn Baldwin 	struct auth_hash *axf;
63ba610be9SJohn Baldwin 	u_int mlen;
64ba610be9SJohn Baldwin };
65ba610be9SJohn Baldwin 
66ba610be9SJohn Baldwin struct ossl_session {
67ba610be9SJohn Baldwin 	struct ossl_session_hash hash;
68ba610be9SJohn Baldwin };
69ba610be9SJohn Baldwin 
70ba610be9SJohn Baldwin static MALLOC_DEFINE(M_OSSL, "ossl", "OpenSSL crypto");
71ba610be9SJohn Baldwin 
72ba610be9SJohn Baldwin static void
73ba610be9SJohn Baldwin ossl_identify(driver_t *driver, device_t parent)
74ba610be9SJohn Baldwin {
75ba610be9SJohn Baldwin 
76ba610be9SJohn Baldwin 	if (device_find_child(parent, "ossl", -1) == NULL)
77ba610be9SJohn Baldwin 		BUS_ADD_CHILD(parent, 10, "ossl", -1);
78ba610be9SJohn Baldwin }
79ba610be9SJohn Baldwin 
80ba610be9SJohn Baldwin static int
81ba610be9SJohn Baldwin ossl_probe(device_t dev)
82ba610be9SJohn Baldwin {
83ba610be9SJohn Baldwin 
84ba610be9SJohn Baldwin 	device_set_desc(dev, "OpenSSL crypto");
85ba610be9SJohn Baldwin 	return (BUS_PROBE_DEFAULT);
86ba610be9SJohn Baldwin }
87ba610be9SJohn Baldwin 
88ba610be9SJohn Baldwin static int
89ba610be9SJohn Baldwin ossl_attach(device_t dev)
90ba610be9SJohn Baldwin {
91ba610be9SJohn Baldwin 	struct ossl_softc *sc;
92ba610be9SJohn Baldwin 
93ba610be9SJohn Baldwin 	sc = device_get_softc(dev);
94ba610be9SJohn Baldwin 
95ba610be9SJohn Baldwin 	ossl_cpuid();
96ba610be9SJohn Baldwin 	sc->sc_cid = crypto_get_driverid(dev, sizeof(struct ossl_session),
97ba610be9SJohn Baldwin 	    CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC |
98ba610be9SJohn Baldwin 	    CRYPTOCAP_F_ACCEL_SOFTWARE);
99ba610be9SJohn Baldwin 	if (sc->sc_cid < 0) {
100ba610be9SJohn Baldwin 		device_printf(dev, "failed to allocate crypto driver id\n");
101ba610be9SJohn Baldwin 		return (ENXIO);
102ba610be9SJohn Baldwin 	}
103ba610be9SJohn Baldwin 
104ba610be9SJohn Baldwin 	return (0);
105ba610be9SJohn Baldwin }
106ba610be9SJohn Baldwin 
107ba610be9SJohn Baldwin static int
108ba610be9SJohn Baldwin ossl_detach(device_t dev)
109ba610be9SJohn Baldwin {
110ba610be9SJohn Baldwin 	struct ossl_softc *sc;
111ba610be9SJohn Baldwin 
112ba610be9SJohn Baldwin 	sc = device_get_softc(dev);
113ba610be9SJohn Baldwin 
114ba610be9SJohn Baldwin 	crypto_unregister_all(sc->sc_cid);
115ba610be9SJohn Baldwin 
116ba610be9SJohn Baldwin 	return (0);
117ba610be9SJohn Baldwin }
118ba610be9SJohn Baldwin 
119ba610be9SJohn Baldwin static struct auth_hash *
120ba610be9SJohn Baldwin ossl_lookup_hash(const struct crypto_session_params *csp)
121ba610be9SJohn Baldwin {
122ba610be9SJohn Baldwin 
123ba610be9SJohn Baldwin 	switch (csp->csp_auth_alg) {
124ba610be9SJohn Baldwin 	case CRYPTO_SHA1:
125ba610be9SJohn Baldwin 	case CRYPTO_SHA1_HMAC:
126ba610be9SJohn Baldwin 		return (&ossl_hash_sha1);
127ba610be9SJohn Baldwin 	case CRYPTO_SHA2_224:
128ba610be9SJohn Baldwin 	case CRYPTO_SHA2_224_HMAC:
129ba610be9SJohn Baldwin 		return (&ossl_hash_sha224);
130ba610be9SJohn Baldwin 	case CRYPTO_SHA2_256:
131ba610be9SJohn Baldwin 	case CRYPTO_SHA2_256_HMAC:
132ba610be9SJohn Baldwin 		return (&ossl_hash_sha256);
133ba610be9SJohn Baldwin 	case CRYPTO_SHA2_384:
134ba610be9SJohn Baldwin 	case CRYPTO_SHA2_384_HMAC:
135ba610be9SJohn Baldwin 		return (&ossl_hash_sha384);
136ba610be9SJohn Baldwin 	case CRYPTO_SHA2_512:
137ba610be9SJohn Baldwin 	case CRYPTO_SHA2_512_HMAC:
138ba610be9SJohn Baldwin 		return (&ossl_hash_sha512);
139a079e38bSJohn Baldwin 	case CRYPTO_POLY1305:
140a079e38bSJohn Baldwin 		return (&ossl_hash_poly1305);
141ba610be9SJohn Baldwin 	default:
142ba610be9SJohn Baldwin 		return (NULL);
143ba610be9SJohn Baldwin 	}
144ba610be9SJohn Baldwin }
145ba610be9SJohn Baldwin 
146ba610be9SJohn Baldwin static int
147ba610be9SJohn Baldwin ossl_probesession(device_t dev, const struct crypto_session_params *csp)
148ba610be9SJohn Baldwin {
149ba610be9SJohn Baldwin 
150ba610be9SJohn Baldwin 	if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD)) !=
151ba610be9SJohn Baldwin 	    0)
152ba610be9SJohn Baldwin 		return (EINVAL);
153ba610be9SJohn Baldwin 	switch (csp->csp_mode) {
154ba610be9SJohn Baldwin 	case CSP_MODE_DIGEST:
155ba610be9SJohn Baldwin 		if (ossl_lookup_hash(csp) == NULL)
156ba610be9SJohn Baldwin 			return (EINVAL);
157ba610be9SJohn Baldwin 		break;
158*92aecd1eSJohn Baldwin 	case CSP_MODE_CIPHER:
159*92aecd1eSJohn Baldwin 		switch (csp->csp_cipher_alg) {
160*92aecd1eSJohn Baldwin 		case CRYPTO_CHACHA20:
161*92aecd1eSJohn Baldwin 			if (csp->csp_cipher_klen != CHACHA_KEY_SIZE)
162*92aecd1eSJohn Baldwin 				return (EINVAL);
163*92aecd1eSJohn Baldwin 			break;
164*92aecd1eSJohn Baldwin 		default:
165*92aecd1eSJohn Baldwin 			return (EINVAL);
166*92aecd1eSJohn Baldwin 		}
167*92aecd1eSJohn Baldwin 		break;
168ba610be9SJohn Baldwin 	default:
169ba610be9SJohn Baldwin 		return (EINVAL);
170ba610be9SJohn Baldwin 	}
171ba610be9SJohn Baldwin 
172ba610be9SJohn Baldwin 	return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
173ba610be9SJohn Baldwin }
174ba610be9SJohn Baldwin 
175*92aecd1eSJohn Baldwin static void
176*92aecd1eSJohn Baldwin ossl_newsession_hash(struct ossl_session *s,
177ba610be9SJohn Baldwin     const struct crypto_session_params *csp)
178ba610be9SJohn Baldwin {
179ba610be9SJohn Baldwin 	struct auth_hash *axf;
180ba610be9SJohn Baldwin 
181ba610be9SJohn Baldwin 	axf = ossl_lookup_hash(csp);
182ba610be9SJohn Baldwin 	s->hash.axf = axf;
183ba610be9SJohn Baldwin 	if (csp->csp_auth_mlen == 0)
184ba610be9SJohn Baldwin 		s->hash.mlen = axf->hashsize;
185ba610be9SJohn Baldwin 	else
186ba610be9SJohn Baldwin 		s->hash.mlen = csp->csp_auth_mlen;
187ba610be9SJohn Baldwin 
188ba610be9SJohn Baldwin 	if (csp->csp_auth_klen == 0) {
189ba610be9SJohn Baldwin 		axf->Init(&s->hash.ictx);
190ba610be9SJohn Baldwin 	} else {
191ba610be9SJohn Baldwin 		if (csp->csp_auth_key != NULL) {
192ba610be9SJohn Baldwin 			fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
193a079e38bSJohn Baldwin 			if (axf->Setkey != NULL) {
194a079e38bSJohn Baldwin 				axf->Init(&s->hash.ictx);
195a079e38bSJohn Baldwin 				axf->Setkey(&s->hash.ictx, csp->csp_auth_key,
196ba610be9SJohn Baldwin 				    csp->csp_auth_klen);
197a079e38bSJohn Baldwin 			} else {
198a079e38bSJohn Baldwin 				hmac_init_ipad(axf, csp->csp_auth_key,
199a079e38bSJohn Baldwin 				    csp->csp_auth_klen, &s->hash.ictx);
200a079e38bSJohn Baldwin 				hmac_init_opad(axf, csp->csp_auth_key,
201a079e38bSJohn Baldwin 				    csp->csp_auth_klen, &s->hash.octx);
202a079e38bSJohn Baldwin 			}
203ba610be9SJohn Baldwin 			fpu_kern_leave(curthread, NULL);
204ba610be9SJohn Baldwin 		}
205ba610be9SJohn Baldwin 	}
206*92aecd1eSJohn Baldwin }
207*92aecd1eSJohn Baldwin 
208*92aecd1eSJohn Baldwin static int
209*92aecd1eSJohn Baldwin ossl_newsession(device_t dev, crypto_session_t cses,
210*92aecd1eSJohn Baldwin     const struct crypto_session_params *csp)
211*92aecd1eSJohn Baldwin {
212*92aecd1eSJohn Baldwin 	struct ossl_session *s;
213*92aecd1eSJohn Baldwin 
214*92aecd1eSJohn Baldwin 	s = crypto_get_driver_session(cses);
215*92aecd1eSJohn Baldwin 	switch (csp->csp_mode) {
216*92aecd1eSJohn Baldwin 	case CSP_MODE_DIGEST:
217*92aecd1eSJohn Baldwin 		ossl_newsession_hash(s, csp);
218*92aecd1eSJohn Baldwin 		break;
219*92aecd1eSJohn Baldwin 	}
220*92aecd1eSJohn Baldwin 
221ba610be9SJohn Baldwin 	return (0);
222ba610be9SJohn Baldwin }
223ba610be9SJohn Baldwin 
224ba610be9SJohn Baldwin static int
225*92aecd1eSJohn Baldwin ossl_process_hash(struct ossl_session *s, struct cryptop *crp,
226*92aecd1eSJohn Baldwin     const struct crypto_session_params *csp)
227ba610be9SJohn Baldwin {
228ba610be9SJohn Baldwin 	struct ossl_hash_context ctx;
229ba610be9SJohn Baldwin 	char digest[HASH_MAX_LEN];
230ba610be9SJohn Baldwin 	struct auth_hash *axf;
231ba610be9SJohn Baldwin 	int error;
232ba610be9SJohn Baldwin 
233ba610be9SJohn Baldwin 	axf = s->hash.axf;
234ba610be9SJohn Baldwin 
235a079e38bSJohn Baldwin 	if (crp->crp_auth_key == NULL) {
236ba610be9SJohn Baldwin 		ctx = s->hash.ictx;
237a079e38bSJohn Baldwin 	} else {
238a079e38bSJohn Baldwin 		if (axf->Setkey != NULL) {
239a079e38bSJohn Baldwin 			axf->Init(&ctx);
240a079e38bSJohn Baldwin 			axf->Setkey(&ctx, crp->crp_auth_key,
241a079e38bSJohn Baldwin 			    csp->csp_auth_klen);
242a079e38bSJohn Baldwin 		} else {
243a079e38bSJohn Baldwin 			hmac_init_ipad(axf, crp->crp_auth_key,
244a079e38bSJohn Baldwin 			    csp->csp_auth_klen, &ctx);
245a079e38bSJohn Baldwin 		}
246a079e38bSJohn Baldwin 	}
247ba610be9SJohn Baldwin 
248ba610be9SJohn Baldwin 	if (crp->crp_aad != NULL)
249ba610be9SJohn Baldwin 		error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
250ba610be9SJohn Baldwin 	else
251ba610be9SJohn Baldwin 		error = crypto_apply(crp, crp->crp_aad_start,
252ba610be9SJohn Baldwin 		    crp->crp_aad_length, axf->Update, &ctx);
253ba610be9SJohn Baldwin 	if (error)
254ba610be9SJohn Baldwin 		goto out;
255ba610be9SJohn Baldwin 
256ba610be9SJohn Baldwin 	error = crypto_apply(crp, crp->crp_payload_start,
257ba610be9SJohn Baldwin 	    crp->crp_payload_length, axf->Update, &ctx);
258ba610be9SJohn Baldwin 	if (error)
259ba610be9SJohn Baldwin 		goto out;
260ba610be9SJohn Baldwin 
261ba610be9SJohn Baldwin 	axf->Final(digest, &ctx);
262ba610be9SJohn Baldwin 
263a079e38bSJohn Baldwin 	if (csp->csp_auth_klen != 0 && axf->Setkey == NULL) {
264a079e38bSJohn Baldwin 		if (crp->crp_auth_key == NULL)
265ba610be9SJohn Baldwin 			ctx = s->hash.octx;
266a079e38bSJohn Baldwin 		else
267a079e38bSJohn Baldwin 			hmac_init_opad(axf, crp->crp_auth_key,
268a079e38bSJohn Baldwin 			    csp->csp_auth_klen, &ctx);
269ba610be9SJohn Baldwin 		axf->Update(&ctx, digest, axf->hashsize);
270ba610be9SJohn Baldwin 		axf->Final(digest, &ctx);
271ba610be9SJohn Baldwin 	}
272ba610be9SJohn Baldwin 
273ba610be9SJohn Baldwin 	if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
274ba610be9SJohn Baldwin 		char digest2[HASH_MAX_LEN];
275ba610be9SJohn Baldwin 
276ba610be9SJohn Baldwin 		crypto_copydata(crp, crp->crp_digest_start, s->hash.mlen,
277ba610be9SJohn Baldwin 		    digest2);
278ba610be9SJohn Baldwin 		if (timingsafe_bcmp(digest, digest2, s->hash.mlen) != 0)
279ba610be9SJohn Baldwin 			error = EBADMSG;
280ba610be9SJohn Baldwin 		explicit_bzero(digest2, sizeof(digest2));
281ba610be9SJohn Baldwin 	} else {
282ba610be9SJohn Baldwin 		crypto_copyback(crp, crp->crp_digest_start, s->hash.mlen,
283ba610be9SJohn Baldwin 		    digest);
284ba610be9SJohn Baldwin 	}
285ba610be9SJohn Baldwin 	explicit_bzero(digest, sizeof(digest));
286ba610be9SJohn Baldwin 
287ba610be9SJohn Baldwin out:
288*92aecd1eSJohn Baldwin 	explicit_bzero(&ctx, sizeof(ctx));
289*92aecd1eSJohn Baldwin 	return (error);
290*92aecd1eSJohn Baldwin }
291*92aecd1eSJohn Baldwin 
292*92aecd1eSJohn Baldwin static int
293*92aecd1eSJohn Baldwin ossl_process(device_t dev, struct cryptop *crp, int hint)
294*92aecd1eSJohn Baldwin {
295*92aecd1eSJohn Baldwin 	const struct crypto_session_params *csp;
296*92aecd1eSJohn Baldwin 	struct ossl_session *s;
297*92aecd1eSJohn Baldwin 	int error;
298*92aecd1eSJohn Baldwin 	bool fpu_entered;
299*92aecd1eSJohn Baldwin 
300*92aecd1eSJohn Baldwin 	s = crypto_get_driver_session(crp->crp_session);
301*92aecd1eSJohn Baldwin 	csp = crypto_get_params(crp->crp_session);
302*92aecd1eSJohn Baldwin 
303*92aecd1eSJohn Baldwin 	if (is_fpu_kern_thread(0)) {
304*92aecd1eSJohn Baldwin 		fpu_entered = false;
305*92aecd1eSJohn Baldwin 	} else {
306*92aecd1eSJohn Baldwin 		fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
307*92aecd1eSJohn Baldwin 		fpu_entered = true;
308*92aecd1eSJohn Baldwin 	}
309*92aecd1eSJohn Baldwin 
310*92aecd1eSJohn Baldwin 	switch (csp->csp_mode) {
311*92aecd1eSJohn Baldwin 	case CSP_MODE_DIGEST:
312*92aecd1eSJohn Baldwin 		error = ossl_process_hash(s, crp, csp);
313*92aecd1eSJohn Baldwin 		break;
314*92aecd1eSJohn Baldwin 	case CSP_MODE_CIPHER:
315*92aecd1eSJohn Baldwin 		error = ossl_chacha20(crp, csp);
316*92aecd1eSJohn Baldwin 		break;
317*92aecd1eSJohn Baldwin 	default:
318*92aecd1eSJohn Baldwin 		__assert_unreachable();
319*92aecd1eSJohn Baldwin 	}
320*92aecd1eSJohn Baldwin 
321ba610be9SJohn Baldwin 	if (fpu_entered)
322ba610be9SJohn Baldwin 		fpu_kern_leave(curthread, NULL);
323ba610be9SJohn Baldwin 
324ba610be9SJohn Baldwin 	crp->crp_etype = error;
325ba610be9SJohn Baldwin 	crypto_done(crp);
326ba610be9SJohn Baldwin 
327ba610be9SJohn Baldwin 	return (0);
328ba610be9SJohn Baldwin }
329ba610be9SJohn Baldwin 
330ba610be9SJohn Baldwin static device_method_t ossl_methods[] = {
331ba610be9SJohn Baldwin 	DEVMETHOD(device_identify,	ossl_identify),
332ba610be9SJohn Baldwin 	DEVMETHOD(device_probe,		ossl_probe),
333ba610be9SJohn Baldwin 	DEVMETHOD(device_attach,	ossl_attach),
334ba610be9SJohn Baldwin 	DEVMETHOD(device_detach,	ossl_detach),
335ba610be9SJohn Baldwin 
336ba610be9SJohn Baldwin 	DEVMETHOD(cryptodev_probesession, ossl_probesession),
337ba610be9SJohn Baldwin 	DEVMETHOD(cryptodev_newsession,	ossl_newsession),
338ba610be9SJohn Baldwin 	DEVMETHOD(cryptodev_process,	ossl_process),
339ba610be9SJohn Baldwin 
340ba610be9SJohn Baldwin 	DEVMETHOD_END
341ba610be9SJohn Baldwin };
342ba610be9SJohn Baldwin 
343ba610be9SJohn Baldwin static driver_t ossl_driver = {
344ba610be9SJohn Baldwin 	"ossl",
345ba610be9SJohn Baldwin 	ossl_methods,
346ba610be9SJohn Baldwin 	sizeof(struct ossl_softc)
347ba610be9SJohn Baldwin };
348ba610be9SJohn Baldwin 
349ba610be9SJohn Baldwin static devclass_t ossl_devclass;
350ba610be9SJohn Baldwin 
351ba610be9SJohn Baldwin DRIVER_MODULE(ossl, nexus, ossl_driver, ossl_devclass, NULL, NULL);
352ba610be9SJohn Baldwin MODULE_VERSION(ossl, 1);
353ba610be9SJohn Baldwin MODULE_DEPEND(ossl, crypto, 1, 1, 1);
354