2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2020 Netflix, Inc
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer,
11 * without modification.
12 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
14 * redistribution must be conditioned upon including a substantially
15 * similar Disclaimer requirement for further binary redistribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
23 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGES.
32 * A driver for the OpenCrypto framework which uses assembly routines
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
39 #include <sys/types.h>
41 #include <sys/kernel.h>
42 #include <sys/malloc.h>
43 #include <sys/module.h>
45 #include <machine/fpu.h>
47 #include <opencrypto/cryptodev.h>
48 #include <opencrypto/xform_auth.h>
50 #include <crypto/openssl/ossl.h>
52 #include "cryptodev_if.h"
58 struct ossl_session_hash {
59 struct ossl_hash_context ictx;
60 struct ossl_hash_context octx;
61 struct auth_hash *axf;
66 struct ossl_session_hash hash;
69 static MALLOC_DEFINE(M_OSSL, "ossl", "OpenSSL crypto");
72 ossl_identify(driver_t *driver, device_t parent)
75 if (device_find_child(parent, "ossl", -1) == NULL)
76 BUS_ADD_CHILD(parent, 10, "ossl", -1);
80 ossl_probe(device_t dev)
83 device_set_desc(dev, "OpenSSL crypto");
84 return (BUS_PROBE_DEFAULT);
88 ossl_attach(device_t dev)
90 struct ossl_softc *sc;
92 sc = device_get_softc(dev);
95 sc->sc_cid = crypto_get_driverid(dev, sizeof(struct ossl_session),
96 CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC |
97 CRYPTOCAP_F_ACCEL_SOFTWARE);
99 device_printf(dev, "failed to allocate crypto driver id\n");
107 ossl_detach(device_t dev)
109 struct ossl_softc *sc;
111 sc = device_get_softc(dev);
113 crypto_unregister_all(sc->sc_cid);
118 static struct auth_hash *
119 ossl_lookup_hash(const struct crypto_session_params *csp)
122 switch (csp->csp_auth_alg) {
124 case CRYPTO_SHA1_HMAC:
125 return (&ossl_hash_sha1);
126 case CRYPTO_SHA2_224:
127 case CRYPTO_SHA2_224_HMAC:
128 return (&ossl_hash_sha224);
129 case CRYPTO_SHA2_256:
130 case CRYPTO_SHA2_256_HMAC:
131 return (&ossl_hash_sha256);
132 case CRYPTO_SHA2_384:
133 case CRYPTO_SHA2_384_HMAC:
134 return (&ossl_hash_sha384);
135 case CRYPTO_SHA2_512:
136 case CRYPTO_SHA2_512_HMAC:
137 return (&ossl_hash_sha512);
144 ossl_probesession(device_t dev, const struct crypto_session_params *csp)
147 if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD)) !=
150 switch (csp->csp_mode) {
151 case CSP_MODE_DIGEST:
152 if (ossl_lookup_hash(csp) == NULL)
159 return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
163 ossl_setkey_hmac(struct ossl_session *s, const void *key, int klen)
166 hmac_init_ipad(s->hash.axf, key, klen, &s->hash.ictx);
167 hmac_init_opad(s->hash.axf, key, klen, &s->hash.octx);
171 ossl_newsession(device_t dev, crypto_session_t cses,
172 const struct crypto_session_params *csp)
174 struct ossl_session *s;
175 struct auth_hash *axf;
177 s = crypto_get_driver_session(cses);
179 axf = ossl_lookup_hash(csp);
181 if (csp->csp_auth_mlen == 0)
182 s->hash.mlen = axf->hashsize;
184 s->hash.mlen = csp->csp_auth_mlen;
186 if (csp->csp_auth_klen == 0) {
187 axf->Init(&s->hash.ictx);
189 if (csp->csp_auth_key != NULL) {
190 fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
191 ossl_setkey_hmac(s, csp->csp_auth_key,
193 fpu_kern_leave(curthread, NULL);
200 ossl_process(device_t dev, struct cryptop *crp, int hint)
202 struct ossl_hash_context ctx;
203 char digest[HASH_MAX_LEN];
204 const struct crypto_session_params *csp;
205 struct ossl_session *s;
206 struct auth_hash *axf;
210 s = crypto_get_driver_session(crp->crp_session);
211 csp = crypto_get_params(crp->crp_session);
214 if (is_fpu_kern_thread(0)) {
217 fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
221 if (crp->crp_auth_key != NULL)
222 ossl_setkey_hmac(s, crp->crp_auth_key, csp->csp_auth_klen);
226 if (crp->crp_aad != NULL)
227 error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
229 error = crypto_apply(crp, crp->crp_aad_start,
230 crp->crp_aad_length, axf->Update, &ctx);
234 error = crypto_apply(crp, crp->crp_payload_start,
235 crp->crp_payload_length, axf->Update, &ctx);
239 axf->Final(digest, &ctx);
241 if (csp->csp_auth_klen != 0) {
243 axf->Update(&ctx, digest, axf->hashsize);
244 axf->Final(digest, &ctx);
247 if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
248 char digest2[HASH_MAX_LEN];
250 crypto_copydata(crp, crp->crp_digest_start, s->hash.mlen,
252 if (timingsafe_bcmp(digest, digest2, s->hash.mlen) != 0)
254 explicit_bzero(digest2, sizeof(digest2));
256 crypto_copyback(crp, crp->crp_digest_start, s->hash.mlen,
259 explicit_bzero(digest, sizeof(digest));
263 fpu_kern_leave(curthread, NULL);
265 crp->crp_etype = error;
268 explicit_bzero(&ctx, sizeof(ctx));
272 static device_method_t ossl_methods[] = {
273 DEVMETHOD(device_identify, ossl_identify),
274 DEVMETHOD(device_probe, ossl_probe),
275 DEVMETHOD(device_attach, ossl_attach),
276 DEVMETHOD(device_detach, ossl_detach),
278 DEVMETHOD(cryptodev_probesession, ossl_probesession),
279 DEVMETHOD(cryptodev_newsession, ossl_newsession),
280 DEVMETHOD(cryptodev_process, ossl_process),
285 static driver_t ossl_driver = {
288 sizeof(struct ossl_softc)
291 static devclass_t ossl_devclass;
293 DRIVER_MODULE(ossl, nexus, ossl_driver, ossl_devclass, NULL, NULL);
294 MODULE_VERSION(ossl, 1);
295 MODULE_DEPEND(ossl, crypto, 1, 1, 1);