Path: blob/main/sys/crypto/blake2/blake2_cryptodev.c
39536 views
/*-1* Copyright (c) 2018 Conrad Meyer <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#include <sys/param.h>27#include <sys/bus.h>28#include <sys/kernel.h>29#include <sys/kobj.h>30#include <sys/malloc.h>31#include <sys/module.h>32#include <sys/mutex.h>33#include <sys/smp.h>3435#include <blake2.h>3637#include <opencrypto/cryptodev.h>38#include <cryptodev_if.h>3940#include <machine/fpu.h>4142struct blake2_session {43size_t mlen;44};45CTASSERT((size_t)BLAKE2B_KEYBYTES > (size_t)BLAKE2S_KEYBYTES);4647struct blake2_softc {48int32_t cid;49};5051static int blake2_cipher_setup(struct blake2_session *ses,52const struct crypto_session_params *csp);53static int blake2_cipher_process(struct blake2_session *ses,54struct cryptop *crp);5556MALLOC_DEFINE(M_BLAKE2, "blake2_data", "Blake2 Data");5758static void59blake2_identify(driver_t *drv, device_t parent)60{6162/* NB: order 10 is so we get attached after h/w devices */63if (device_find_child(parent, "blaketwo", DEVICE_UNIT_ANY) == NULL &&64BUS_ADD_CHILD(parent, 10, "blaketwo", DEVICE_UNIT_ANY) == 0)65panic("blaketwo: could not attach");66}6768static int69blake2_probe(device_t dev)70{71device_set_desc(dev, "Blake2");72return (0);73}7475static int76blake2_attach(device_t dev)77{78struct blake2_softc *sc;7980sc = device_get_softc(dev);8182sc->cid = crypto_get_driverid(dev, sizeof(struct blake2_session),83CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC |84CRYPTOCAP_F_ACCEL_SOFTWARE);85if (sc->cid < 0) {86device_printf(dev, "Could not get crypto driver id.\n");87return (ENOMEM);88}8990return (0);91}9293static int94blake2_detach(device_t dev)95{96struct blake2_softc *sc;9798sc = device_get_softc(dev);99100crypto_unregister_all(sc->cid);101102return (0);103}104105static int106blake2_probesession(device_t dev, const struct crypto_session_params *csp)107{108109if (csp->csp_flags != 0)110return (EINVAL);111switch (csp->csp_mode) {112case CSP_MODE_DIGEST:113switch (csp->csp_auth_alg) {114case CRYPTO_BLAKE2B:115case CRYPTO_BLAKE2S:116break;117default:118return (EINVAL);119}120break;121default:122return (EINVAL);123}124return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);125}126127static int128blake2_newsession(device_t dev, crypto_session_t cses,129const struct crypto_session_params *csp)130{131struct blake2_session *ses;132int error;133134ses = crypto_get_driver_session(cses);135136error = blake2_cipher_setup(ses, csp);137if (error != 0) {138CRYPTDEB("setup failed");139return (error);140}141142return (0);143}144145static int146blake2_process(device_t dev, struct cryptop *crp, int hint __unused)147{148struct blake2_session *ses;149int error;150151ses = crypto_get_driver_session(crp->crp_session);152error = blake2_cipher_process(ses, crp);153154crp->crp_etype = error;155crypto_done(crp);156return (0);157}158159static device_method_t blake2_methods[] = {160DEVMETHOD(device_identify, blake2_identify),161DEVMETHOD(device_probe, blake2_probe),162DEVMETHOD(device_attach, blake2_attach),163DEVMETHOD(device_detach, blake2_detach),164165DEVMETHOD(cryptodev_probesession, blake2_probesession),166DEVMETHOD(cryptodev_newsession, blake2_newsession),167DEVMETHOD(cryptodev_process, blake2_process),168169DEVMETHOD_END170};171172static driver_t blake2_driver = {173"blaketwo",174blake2_methods,175sizeof(struct blake2_softc),176};177178DRIVER_MODULE(blake2, nexus, blake2_driver, 0, 0);179MODULE_VERSION(blake2, 1);180MODULE_DEPEND(blake2, crypto, 1, 1, 1);181182static bool183blake2_check_klen(const struct crypto_session_params *csp, unsigned klen)184{185186if (csp->csp_auth_alg == CRYPTO_BLAKE2S)187return (klen <= BLAKE2S_KEYBYTES);188else189return (klen <= BLAKE2B_KEYBYTES);190}191192static int193blake2_cipher_setup(struct blake2_session *ses,194const struct crypto_session_params *csp)195{196int hashlen;197198CTASSERT((size_t)BLAKE2S_OUTBYTES <= (size_t)BLAKE2B_OUTBYTES);199200if (!blake2_check_klen(csp, csp->csp_auth_klen))201return (EINVAL);202203if (csp->csp_auth_mlen < 0)204return (EINVAL);205206switch (csp->csp_auth_alg) {207case CRYPTO_BLAKE2S:208hashlen = BLAKE2S_OUTBYTES;209break;210case CRYPTO_BLAKE2B:211hashlen = BLAKE2B_OUTBYTES;212break;213default:214return (EINVAL);215}216217if (csp->csp_auth_mlen > hashlen)218return (EINVAL);219220if (csp->csp_auth_mlen == 0)221ses->mlen = hashlen;222else223ses->mlen = csp->csp_auth_mlen;224return (0);225}226227static int228blake2b_applicator(void *state, const void *buf, u_int len)229{230int rc;231232rc = blake2b_update(state, buf, len);233if (rc != 0)234return (EINVAL);235return (0);236}237238static int239blake2s_applicator(void *state, const void *buf, u_int len)240{241int rc;242243rc = blake2s_update(state, buf, len);244if (rc != 0)245return (EINVAL);246return (0);247}248249static int250blake2_cipher_process(struct blake2_session *ses, struct cryptop *crp)251{252union {253blake2b_state sb;254blake2s_state ss;255} bctx;256char res[BLAKE2B_OUTBYTES], res2[BLAKE2B_OUTBYTES];257const struct crypto_session_params *csp;258const void *key;259int error, rc;260unsigned klen;261262csp = crypto_get_params(crp->crp_session);263if (crp->crp_auth_key != NULL)264key = crp->crp_auth_key;265else266key = csp->csp_auth_key;267klen = csp->csp_auth_klen;268269fpu_kern_enter(curthread, NULL, FPU_KERN_NORMAL | FPU_KERN_NOCTX);270271switch (csp->csp_auth_alg) {272case CRYPTO_BLAKE2B:273if (klen > 0)274rc = blake2b_init_key(&bctx.sb, ses->mlen, key, klen);275else276rc = blake2b_init(&bctx.sb, ses->mlen);277if (rc != 0) {278error = EINVAL;279break;280}281error = crypto_apply(crp, crp->crp_payload_start,282crp->crp_payload_length, blake2b_applicator, &bctx.sb);283if (error != 0)284break;285rc = blake2b_final(&bctx.sb, res, ses->mlen);286if (rc != 0)287error = EINVAL;288break;289case CRYPTO_BLAKE2S:290if (klen > 0)291rc = blake2s_init_key(&bctx.ss, ses->mlen, key, klen);292else293rc = blake2s_init(&bctx.ss, ses->mlen);294if (rc != 0) {295error = EINVAL;296break;297}298error = crypto_apply(crp, crp->crp_payload_start,299crp->crp_payload_length, blake2s_applicator, &bctx.ss);300if (error != 0)301break;302rc = blake2s_final(&bctx.ss, res, ses->mlen);303if (rc != 0)304error = EINVAL;305break;306default:307__assert_unreachable();308}309310fpu_kern_leave(curthread, NULL);311312if (error != 0)313return (error);314315if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {316crypto_copydata(crp, crp->crp_digest_start, ses->mlen, res2);317if (timingsafe_bcmp(res, res2, ses->mlen) != 0)318error = EBADMSG;319} else320crypto_copyback(crp, crp->crp_digest_start, ses->mlen, res);321322return (error);323}324325326