1fd86ae68SMitchell Horne /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 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/types.h> 37ba610be9SJohn Baldwin #include <sys/bus.h> 38ba610be9SJohn Baldwin #include <sys/kernel.h> 39ba610be9SJohn Baldwin #include <sys/malloc.h> 40ba610be9SJohn Baldwin #include <sys/module.h> 41fd86ae68SMitchell Horne 42ba610be9SJohn Baldwin #include <machine/fpu.h> 43ba610be9SJohn Baldwin 44ba610be9SJohn Baldwin #include <opencrypto/cryptodev.h> 45ba610be9SJohn Baldwin #include <opencrypto/xform_auth.h> 46ba610be9SJohn Baldwin 47ba610be9SJohn Baldwin #include <crypto/openssl/ossl.h> 4892aecd1eSJohn Baldwin #include <crypto/openssl/ossl_chacha.h> 49197ff4c3SKornel Duleba #include <crypto/openssl/ossl_cipher.h> 50ba610be9SJohn Baldwin 51ba610be9SJohn Baldwin #include "cryptodev_if.h" 52ba610be9SJohn Baldwin 53ba610be9SJohn Baldwin static MALLOC_DEFINE(M_OSSL, "ossl", "OpenSSL crypto"); 54ba610be9SJohn Baldwin 55ba610be9SJohn Baldwin static void 56ba610be9SJohn Baldwin ossl_identify(driver_t *driver, device_t parent) 57ba610be9SJohn Baldwin { 58ba610be9SJohn Baldwin 59ba610be9SJohn Baldwin if (device_find_child(parent, "ossl", -1) == NULL) 60*a05a6804SWarner Losh BUS_ADD_CHILD(parent, 10, "ossl", DEVICE_UNIT_ANY); 61ba610be9SJohn Baldwin } 62ba610be9SJohn Baldwin 63ba610be9SJohn Baldwin static int 64ba610be9SJohn Baldwin ossl_probe(device_t dev) 65ba610be9SJohn Baldwin { 66ba610be9SJohn Baldwin 67ba610be9SJohn Baldwin device_set_desc(dev, "OpenSSL crypto"); 68ba610be9SJohn Baldwin return (BUS_PROBE_DEFAULT); 69ba610be9SJohn Baldwin } 70ba610be9SJohn Baldwin 71ba610be9SJohn Baldwin static int 72ba610be9SJohn Baldwin ossl_attach(device_t dev) 73ba610be9SJohn Baldwin { 74ba610be9SJohn Baldwin struct ossl_softc *sc; 75ba610be9SJohn Baldwin 76ba610be9SJohn Baldwin sc = device_get_softc(dev); 77ba610be9SJohn Baldwin 789a3444d9SMark Johnston sc->has_aes = sc->has_aes_gcm = false; 799a3444d9SMark Johnston 80197ff4c3SKornel Duleba ossl_cpuid(sc); 81ba610be9SJohn Baldwin sc->sc_cid = crypto_get_driverid(dev, sizeof(struct ossl_session), 82ba610be9SJohn Baldwin CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC | 83ba610be9SJohn Baldwin CRYPTOCAP_F_ACCEL_SOFTWARE); 84ba610be9SJohn Baldwin if (sc->sc_cid < 0) { 85ba610be9SJohn Baldwin device_printf(dev, "failed to allocate crypto driver id\n"); 86ba610be9SJohn Baldwin return (ENXIO); 87ba610be9SJohn Baldwin } 88ba610be9SJohn Baldwin 89ba610be9SJohn Baldwin return (0); 90ba610be9SJohn Baldwin } 91ba610be9SJohn Baldwin 92ba610be9SJohn Baldwin static int 93ba610be9SJohn Baldwin ossl_detach(device_t dev) 94ba610be9SJohn Baldwin { 95ba610be9SJohn Baldwin struct ossl_softc *sc; 96ba610be9SJohn Baldwin 97ba610be9SJohn Baldwin sc = device_get_softc(dev); 98ba610be9SJohn Baldwin 99ba610be9SJohn Baldwin crypto_unregister_all(sc->sc_cid); 100ba610be9SJohn Baldwin 101ba610be9SJohn Baldwin return (0); 102ba610be9SJohn Baldwin } 103ba610be9SJohn Baldwin 104ba610be9SJohn Baldwin static struct auth_hash * 105ba610be9SJohn Baldwin ossl_lookup_hash(const struct crypto_session_params *csp) 106ba610be9SJohn Baldwin { 107ba610be9SJohn Baldwin 108ba610be9SJohn Baldwin switch (csp->csp_auth_alg) { 109ba610be9SJohn Baldwin case CRYPTO_SHA1: 110ba610be9SJohn Baldwin case CRYPTO_SHA1_HMAC: 111ba610be9SJohn Baldwin return (&ossl_hash_sha1); 112ba610be9SJohn Baldwin case CRYPTO_SHA2_224: 113ba610be9SJohn Baldwin case CRYPTO_SHA2_224_HMAC: 114ba610be9SJohn Baldwin return (&ossl_hash_sha224); 115ba610be9SJohn Baldwin case CRYPTO_SHA2_256: 116ba610be9SJohn Baldwin case CRYPTO_SHA2_256_HMAC: 117ba610be9SJohn Baldwin return (&ossl_hash_sha256); 118ba610be9SJohn Baldwin case CRYPTO_SHA2_384: 119ba610be9SJohn Baldwin case CRYPTO_SHA2_384_HMAC: 120ba610be9SJohn Baldwin return (&ossl_hash_sha384); 121ba610be9SJohn Baldwin case CRYPTO_SHA2_512: 122ba610be9SJohn Baldwin case CRYPTO_SHA2_512_HMAC: 123ba610be9SJohn Baldwin return (&ossl_hash_sha512); 124a079e38bSJohn Baldwin case CRYPTO_POLY1305: 125a079e38bSJohn Baldwin return (&ossl_hash_poly1305); 126ba610be9SJohn Baldwin default: 127ba610be9SJohn Baldwin return (NULL); 128ba610be9SJohn Baldwin } 129ba610be9SJohn Baldwin } 130ba610be9SJohn Baldwin 131197ff4c3SKornel Duleba static struct ossl_cipher* 132197ff4c3SKornel Duleba ossl_lookup_cipher(const struct crypto_session_params *csp) 133197ff4c3SKornel Duleba { 134197ff4c3SKornel Duleba 135197ff4c3SKornel Duleba switch (csp->csp_cipher_alg) { 136197ff4c3SKornel Duleba case CRYPTO_AES_CBC: 137197ff4c3SKornel Duleba switch (csp->csp_cipher_klen * 8) { 138197ff4c3SKornel Duleba case 128: 139197ff4c3SKornel Duleba case 192: 140197ff4c3SKornel Duleba case 256: 141197ff4c3SKornel Duleba break; 142197ff4c3SKornel Duleba default: 143197ff4c3SKornel Duleba return (NULL); 144197ff4c3SKornel Duleba } 145197ff4c3SKornel Duleba return (&ossl_cipher_aes_cbc); 1469a3444d9SMark Johnston case CRYPTO_AES_NIST_GCM_16: 1479a3444d9SMark Johnston switch (csp->csp_cipher_klen * 8) { 1489a3444d9SMark Johnston case 128: 1499a3444d9SMark Johnston case 192: 1509a3444d9SMark Johnston case 256: 1519a3444d9SMark Johnston break; 1529a3444d9SMark Johnston default: 1539a3444d9SMark Johnston return (NULL); 1549a3444d9SMark Johnston } 1559a3444d9SMark Johnston return (&ossl_cipher_aes_gcm); 156197ff4c3SKornel Duleba case CRYPTO_CHACHA20: 157197ff4c3SKornel Duleba if (csp->csp_cipher_klen != CHACHA_KEY_SIZE) 158197ff4c3SKornel Duleba return (NULL); 159197ff4c3SKornel Duleba return (&ossl_cipher_chacha20); 160197ff4c3SKornel Duleba default: 161197ff4c3SKornel Duleba return (NULL); 162197ff4c3SKornel Duleba } 163197ff4c3SKornel Duleba } 164197ff4c3SKornel Duleba 165ba610be9SJohn Baldwin static int 166ba610be9SJohn Baldwin ossl_probesession(device_t dev, const struct crypto_session_params *csp) 167ba610be9SJohn Baldwin { 168197ff4c3SKornel Duleba struct ossl_softc *sc = device_get_softc(dev); 169ba610be9SJohn Baldwin 170ba610be9SJohn Baldwin if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD)) != 171ba610be9SJohn Baldwin 0) 172ba610be9SJohn Baldwin return (EINVAL); 173ba610be9SJohn Baldwin switch (csp->csp_mode) { 174ba610be9SJohn Baldwin case CSP_MODE_DIGEST: 175ba610be9SJohn Baldwin if (ossl_lookup_hash(csp) == NULL) 176ba610be9SJohn Baldwin return (EINVAL); 177ba610be9SJohn Baldwin break; 17892aecd1eSJohn Baldwin case CSP_MODE_CIPHER: 179197ff4c3SKornel Duleba if (csp->csp_cipher_alg != CRYPTO_CHACHA20 && !sc->has_aes) 18092aecd1eSJohn Baldwin return (EINVAL); 181197ff4c3SKornel Duleba if (ossl_lookup_cipher(csp) == NULL) 18292aecd1eSJohn Baldwin return (EINVAL); 18392aecd1eSJohn Baldwin break; 184c4026909SKornel Duleba case CSP_MODE_ETA: 185c4026909SKornel Duleba if (!sc->has_aes || 186c4026909SKornel Duleba csp->csp_cipher_alg == CRYPTO_CHACHA20 || 187c4026909SKornel Duleba ossl_lookup_hash(csp) == NULL || 188c4026909SKornel Duleba ossl_lookup_cipher(csp) == NULL) 189c4026909SKornel Duleba return (EINVAL); 190c4026909SKornel Duleba break; 19178991a93SJohn Baldwin case CSP_MODE_AEAD: 19278991a93SJohn Baldwin switch (csp->csp_cipher_alg) { 19378991a93SJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 19478991a93SJohn Baldwin break; 1959a3444d9SMark Johnston case CRYPTO_AES_NIST_GCM_16: 1969a3444d9SMark Johnston if (!sc->has_aes_gcm || ossl_lookup_cipher(csp) == NULL) 1979a3444d9SMark Johnston return (EINVAL); 1989a3444d9SMark Johnston if (csp->csp_ivlen != AES_GCM_IV_LEN) 1999a3444d9SMark Johnston return (EINVAL); 2009a3444d9SMark Johnston if (csp->csp_auth_mlen != 0 && 2019a3444d9SMark Johnston csp->csp_auth_mlen != GMAC_DIGEST_LEN) 2029a3444d9SMark Johnston return (EINVAL); 2039a3444d9SMark Johnston break; 20478991a93SJohn Baldwin default: 20578991a93SJohn Baldwin return (EINVAL); 20678991a93SJohn Baldwin } 20778991a93SJohn Baldwin break; 208ba610be9SJohn Baldwin default: 209ba610be9SJohn Baldwin return (EINVAL); 210ba610be9SJohn Baldwin } 211ba610be9SJohn Baldwin 212ba610be9SJohn Baldwin return (CRYPTODEV_PROBE_ACCEL_SOFTWARE); 213ba610be9SJohn Baldwin } 214ba610be9SJohn Baldwin 21592aecd1eSJohn Baldwin static void 21692aecd1eSJohn Baldwin ossl_newsession_hash(struct ossl_session *s, 217ba610be9SJohn Baldwin const struct crypto_session_params *csp) 218ba610be9SJohn Baldwin { 219ba610be9SJohn Baldwin struct auth_hash *axf; 220ba610be9SJohn Baldwin 221ba610be9SJohn Baldwin axf = ossl_lookup_hash(csp); 222ba610be9SJohn Baldwin s->hash.axf = axf; 223ba610be9SJohn Baldwin if (csp->csp_auth_mlen == 0) 224ba610be9SJohn Baldwin s->hash.mlen = axf->hashsize; 225ba610be9SJohn Baldwin else 226ba610be9SJohn Baldwin s->hash.mlen = csp->csp_auth_mlen; 227ba610be9SJohn Baldwin 228ba610be9SJohn Baldwin if (csp->csp_auth_klen == 0) { 229ba610be9SJohn Baldwin axf->Init(&s->hash.ictx); 230ba610be9SJohn Baldwin } else { 231ba610be9SJohn Baldwin if (csp->csp_auth_key != NULL) { 232ba610be9SJohn Baldwin fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX); 233a079e38bSJohn Baldwin if (axf->Setkey != NULL) { 234a079e38bSJohn Baldwin axf->Init(&s->hash.ictx); 235a079e38bSJohn Baldwin axf->Setkey(&s->hash.ictx, csp->csp_auth_key, 236ba610be9SJohn Baldwin csp->csp_auth_klen); 237a079e38bSJohn Baldwin } else { 238a079e38bSJohn Baldwin hmac_init_ipad(axf, csp->csp_auth_key, 239a079e38bSJohn Baldwin csp->csp_auth_klen, &s->hash.ictx); 240a079e38bSJohn Baldwin hmac_init_opad(axf, csp->csp_auth_key, 241a079e38bSJohn Baldwin csp->csp_auth_klen, &s->hash.octx); 242a079e38bSJohn Baldwin } 243ba610be9SJohn Baldwin fpu_kern_leave(curthread, NULL); 244ba610be9SJohn Baldwin } 245ba610be9SJohn Baldwin } 24692aecd1eSJohn Baldwin } 24792aecd1eSJohn Baldwin 24892aecd1eSJohn Baldwin static int 249197ff4c3SKornel Duleba ossl_newsession_cipher(struct ossl_session *s, 250197ff4c3SKornel Duleba const struct crypto_session_params *csp) 251197ff4c3SKornel Duleba { 252197ff4c3SKornel Duleba struct ossl_cipher *cipher; 253197ff4c3SKornel Duleba int error = 0; 254197ff4c3SKornel Duleba 255197ff4c3SKornel Duleba cipher = ossl_lookup_cipher(csp); 256197ff4c3SKornel Duleba if (cipher == NULL) 257197ff4c3SKornel Duleba return (EINVAL); 258197ff4c3SKornel Duleba 259197ff4c3SKornel Duleba s->cipher.cipher = cipher; 260197ff4c3SKornel Duleba 261197ff4c3SKornel Duleba if (csp->csp_cipher_key == NULL) 262197ff4c3SKornel Duleba return (0); 263197ff4c3SKornel Duleba 264197ff4c3SKornel Duleba fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX); 265197ff4c3SKornel Duleba if (cipher->set_encrypt_key != NULL) { 266197ff4c3SKornel Duleba error = cipher->set_encrypt_key(csp->csp_cipher_key, 267197ff4c3SKornel Duleba 8 * csp->csp_cipher_klen, &s->cipher.enc_ctx); 268197ff4c3SKornel Duleba if (error != 0) { 269197ff4c3SKornel Duleba fpu_kern_leave(curthread, NULL); 270197ff4c3SKornel Duleba return (error); 271197ff4c3SKornel Duleba } 272197ff4c3SKornel Duleba } 273197ff4c3SKornel Duleba if (cipher->set_decrypt_key != NULL) 274197ff4c3SKornel Duleba error = cipher->set_decrypt_key(csp->csp_cipher_key, 275197ff4c3SKornel Duleba 8 * csp->csp_cipher_klen, &s->cipher.dec_ctx); 276197ff4c3SKornel Duleba fpu_kern_leave(curthread, NULL); 277197ff4c3SKornel Duleba 278197ff4c3SKornel Duleba return (error); 279197ff4c3SKornel Duleba } 280197ff4c3SKornel Duleba 281197ff4c3SKornel Duleba static int 28292aecd1eSJohn Baldwin ossl_newsession(device_t dev, crypto_session_t cses, 28392aecd1eSJohn Baldwin const struct crypto_session_params *csp) 28492aecd1eSJohn Baldwin { 28592aecd1eSJohn Baldwin struct ossl_session *s; 286197ff4c3SKornel Duleba int error = 0; 28792aecd1eSJohn Baldwin 28892aecd1eSJohn Baldwin s = crypto_get_driver_session(cses); 28992aecd1eSJohn Baldwin switch (csp->csp_mode) { 29092aecd1eSJohn Baldwin case CSP_MODE_DIGEST: 29192aecd1eSJohn Baldwin ossl_newsession_hash(s, csp); 29292aecd1eSJohn Baldwin break; 293197ff4c3SKornel Duleba case CSP_MODE_CIPHER: 294197ff4c3SKornel Duleba error = ossl_newsession_cipher(s, csp); 295197ff4c3SKornel Duleba break; 296c4026909SKornel Duleba case CSP_MODE_ETA: 297c4026909SKornel Duleba ossl_newsession_hash(s, csp); 298c4026909SKornel Duleba error = ossl_newsession_cipher(s, csp); 299c4026909SKornel Duleba break; 3009a3444d9SMark Johnston case CSP_MODE_AEAD: 301474d9290SJohn Baldwin if (csp->csp_cipher_alg != CRYPTO_CHACHA20_POLY1305) 3029a3444d9SMark Johnston error = ossl_newsession_cipher(s, csp); 3039a3444d9SMark Johnston break; 3049a3444d9SMark Johnston default: 3059a3444d9SMark Johnston __assert_unreachable(); 30692aecd1eSJohn Baldwin } 30792aecd1eSJohn Baldwin 308197ff4c3SKornel Duleba return (error); 309ba610be9SJohn Baldwin } 310ba610be9SJohn Baldwin 311ba610be9SJohn Baldwin static int 31292aecd1eSJohn Baldwin ossl_process_hash(struct ossl_session *s, struct cryptop *crp, 31392aecd1eSJohn Baldwin const struct crypto_session_params *csp) 314ba610be9SJohn Baldwin { 315ba610be9SJohn Baldwin struct ossl_hash_context ctx; 316ba610be9SJohn Baldwin char digest[HASH_MAX_LEN]; 317ba610be9SJohn Baldwin struct auth_hash *axf; 318ba610be9SJohn Baldwin int error; 319ba610be9SJohn Baldwin 320ba610be9SJohn Baldwin axf = s->hash.axf; 321ba610be9SJohn Baldwin 322a079e38bSJohn Baldwin if (crp->crp_auth_key == NULL) { 323ba610be9SJohn Baldwin ctx = s->hash.ictx; 324a079e38bSJohn Baldwin } else { 325a079e38bSJohn Baldwin if (axf->Setkey != NULL) { 326a079e38bSJohn Baldwin axf->Init(&ctx); 327a079e38bSJohn Baldwin axf->Setkey(&ctx, crp->crp_auth_key, 328a079e38bSJohn Baldwin csp->csp_auth_klen); 329a079e38bSJohn Baldwin } else { 330a079e38bSJohn Baldwin hmac_init_ipad(axf, crp->crp_auth_key, 331a079e38bSJohn Baldwin csp->csp_auth_klen, &ctx); 332a079e38bSJohn Baldwin } 333a079e38bSJohn Baldwin } 334ba610be9SJohn Baldwin 335ba610be9SJohn Baldwin if (crp->crp_aad != NULL) 336ba610be9SJohn Baldwin error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); 337ba610be9SJohn Baldwin else 338ba610be9SJohn Baldwin error = crypto_apply(crp, crp->crp_aad_start, 339ba610be9SJohn Baldwin crp->crp_aad_length, axf->Update, &ctx); 340ba610be9SJohn Baldwin if (error) 341ba610be9SJohn Baldwin goto out; 342ba610be9SJohn Baldwin 343ba610be9SJohn Baldwin error = crypto_apply(crp, crp->crp_payload_start, 344ba610be9SJohn Baldwin crp->crp_payload_length, axf->Update, &ctx); 345ba610be9SJohn Baldwin if (error) 346ba610be9SJohn Baldwin goto out; 347ba610be9SJohn Baldwin 348ba610be9SJohn Baldwin axf->Final(digest, &ctx); 349ba610be9SJohn Baldwin 350a079e38bSJohn Baldwin if (csp->csp_auth_klen != 0 && axf->Setkey == NULL) { 351a079e38bSJohn Baldwin if (crp->crp_auth_key == NULL) 352ba610be9SJohn Baldwin ctx = s->hash.octx; 353a079e38bSJohn Baldwin else 354a079e38bSJohn Baldwin hmac_init_opad(axf, crp->crp_auth_key, 355a079e38bSJohn Baldwin csp->csp_auth_klen, &ctx); 356ba610be9SJohn Baldwin axf->Update(&ctx, digest, axf->hashsize); 357ba610be9SJohn Baldwin axf->Final(digest, &ctx); 358ba610be9SJohn Baldwin } 359ba610be9SJohn Baldwin 360ba610be9SJohn Baldwin if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { 361ba610be9SJohn Baldwin char digest2[HASH_MAX_LEN]; 362ba610be9SJohn Baldwin 363ba610be9SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, s->hash.mlen, 364ba610be9SJohn Baldwin digest2); 365ba610be9SJohn Baldwin if (timingsafe_bcmp(digest, digest2, s->hash.mlen) != 0) 366ba610be9SJohn Baldwin error = EBADMSG; 367ba610be9SJohn Baldwin explicit_bzero(digest2, sizeof(digest2)); 368ba610be9SJohn Baldwin } else { 369ba610be9SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, s->hash.mlen, 370ba610be9SJohn Baldwin digest); 371ba610be9SJohn Baldwin } 372ba610be9SJohn Baldwin explicit_bzero(digest, sizeof(digest)); 373ba610be9SJohn Baldwin 374ba610be9SJohn Baldwin out: 37592aecd1eSJohn Baldwin explicit_bzero(&ctx, sizeof(ctx)); 37692aecd1eSJohn Baldwin return (error); 37792aecd1eSJohn Baldwin } 37892aecd1eSJohn Baldwin 37992aecd1eSJohn Baldwin static int 3809a3444d9SMark Johnston ossl_process_cipher(struct ossl_session *s, struct cryptop *crp, 3819a3444d9SMark Johnston const struct crypto_session_params *csp) 3829a3444d9SMark Johnston { 3839a3444d9SMark Johnston return (s->cipher.cipher->process(&s->cipher, crp, csp)); 3849a3444d9SMark Johnston } 3859a3444d9SMark Johnston 3869a3444d9SMark Johnston static int 387c4026909SKornel Duleba ossl_process_eta(struct ossl_session *s, struct cryptop *crp, 388c4026909SKornel Duleba const struct crypto_session_params *csp) 389c4026909SKornel Duleba { 390c4026909SKornel Duleba int error; 391c4026909SKornel Duleba 392c4026909SKornel Duleba if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 393c4026909SKornel Duleba error = s->cipher.cipher->process(&s->cipher, crp, csp); 394c4026909SKornel Duleba if (error == 0) 395c4026909SKornel Duleba error = ossl_process_hash(s, crp, csp); 396c4026909SKornel Duleba } else { 397c4026909SKornel Duleba error = ossl_process_hash(s, crp, csp); 398c4026909SKornel Duleba if (error == 0) 399c4026909SKornel Duleba error = s->cipher.cipher->process(&s->cipher, crp, csp); 400c4026909SKornel Duleba } 401c4026909SKornel Duleba 402c4026909SKornel Duleba return (error); 403c4026909SKornel Duleba } 404c4026909SKornel Duleba 405c4026909SKornel Duleba static int 4069a3444d9SMark Johnston ossl_process_aead(struct ossl_session *s, struct cryptop *crp, 4079a3444d9SMark Johnston const struct crypto_session_params *csp) 4089a3444d9SMark Johnston { 4099a3444d9SMark Johnston if (csp->csp_cipher_alg == CRYPTO_CHACHA20_POLY1305) { 4109a3444d9SMark Johnston if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) 4119a3444d9SMark Johnston return (ossl_chacha20_poly1305_encrypt(crp, csp)); 4129a3444d9SMark Johnston else 4139a3444d9SMark Johnston return (ossl_chacha20_poly1305_decrypt(crp, csp)); 4149a3444d9SMark Johnston } else { 4159a3444d9SMark Johnston return (s->cipher.cipher->process(&s->cipher, crp, csp)); 4169a3444d9SMark Johnston } 4179a3444d9SMark Johnston } 4189a3444d9SMark Johnston 4199a3444d9SMark Johnston static int 42092aecd1eSJohn Baldwin ossl_process(device_t dev, struct cryptop *crp, int hint) 42192aecd1eSJohn Baldwin { 42292aecd1eSJohn Baldwin const struct crypto_session_params *csp; 42392aecd1eSJohn Baldwin struct ossl_session *s; 42492aecd1eSJohn Baldwin int error; 42592aecd1eSJohn Baldwin bool fpu_entered; 42692aecd1eSJohn Baldwin 42792aecd1eSJohn Baldwin s = crypto_get_driver_session(crp->crp_session); 42892aecd1eSJohn Baldwin csp = crypto_get_params(crp->crp_session); 42992aecd1eSJohn Baldwin 43092aecd1eSJohn Baldwin if (is_fpu_kern_thread(0)) { 43192aecd1eSJohn Baldwin fpu_entered = false; 43292aecd1eSJohn Baldwin } else { 43392aecd1eSJohn Baldwin fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX); 43492aecd1eSJohn Baldwin fpu_entered = true; 43592aecd1eSJohn Baldwin } 43692aecd1eSJohn Baldwin 43792aecd1eSJohn Baldwin switch (csp->csp_mode) { 43892aecd1eSJohn Baldwin case CSP_MODE_DIGEST: 43992aecd1eSJohn Baldwin error = ossl_process_hash(s, crp, csp); 44092aecd1eSJohn Baldwin break; 44192aecd1eSJohn Baldwin case CSP_MODE_CIPHER: 4429a3444d9SMark Johnston error = ossl_process_cipher(s, crp, csp); 44392aecd1eSJohn Baldwin break; 444c4026909SKornel Duleba case CSP_MODE_ETA: 445c4026909SKornel Duleba error = ossl_process_eta(s, crp, csp); 446c4026909SKornel Duleba break; 44778991a93SJohn Baldwin case CSP_MODE_AEAD: 4489a3444d9SMark Johnston error = ossl_process_aead(s, crp, csp); 44978991a93SJohn Baldwin break; 45092aecd1eSJohn Baldwin default: 45192aecd1eSJohn Baldwin __assert_unreachable(); 45292aecd1eSJohn Baldwin } 45392aecd1eSJohn Baldwin 454ba610be9SJohn Baldwin if (fpu_entered) 455ba610be9SJohn Baldwin fpu_kern_leave(curthread, NULL); 456ba610be9SJohn Baldwin 457ba610be9SJohn Baldwin crp->crp_etype = error; 458ba610be9SJohn Baldwin crypto_done(crp); 459ba610be9SJohn Baldwin 460ba610be9SJohn Baldwin return (0); 461ba610be9SJohn Baldwin } 462ba610be9SJohn Baldwin 463ba610be9SJohn Baldwin static device_method_t ossl_methods[] = { 464ba610be9SJohn Baldwin DEVMETHOD(device_identify, ossl_identify), 465ba610be9SJohn Baldwin DEVMETHOD(device_probe, ossl_probe), 466ba610be9SJohn Baldwin DEVMETHOD(device_attach, ossl_attach), 467ba610be9SJohn Baldwin DEVMETHOD(device_detach, ossl_detach), 468ba610be9SJohn Baldwin 469ba610be9SJohn Baldwin DEVMETHOD(cryptodev_probesession, ossl_probesession), 470ba610be9SJohn Baldwin DEVMETHOD(cryptodev_newsession, ossl_newsession), 471ba610be9SJohn Baldwin DEVMETHOD(cryptodev_process, ossl_process), 472ba610be9SJohn Baldwin 473ba610be9SJohn Baldwin DEVMETHOD_END 474ba610be9SJohn Baldwin }; 475ba610be9SJohn Baldwin 476ba610be9SJohn Baldwin static driver_t ossl_driver = { 477ba610be9SJohn Baldwin "ossl", 478ba610be9SJohn Baldwin ossl_methods, 479ba610be9SJohn Baldwin sizeof(struct ossl_softc) 480ba610be9SJohn Baldwin }; 481ba610be9SJohn Baldwin 482ab050b2bSJohn Baldwin DRIVER_MODULE(ossl, nexus, ossl_driver, NULL, NULL); 483ba610be9SJohn Baldwin MODULE_VERSION(ossl, 1); 484ba610be9SJohn Baldwin MODULE_DEPEND(ossl, crypto, 1, 1, 1); 485