cryptosoft.c revision 184205
1104476Ssam/* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ 2104476Ssam 3139825Simp/*- 4104476Ssam * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) 5167755Ssam * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting 6104476Ssam * 7104476Ssam * This code was written by Angelos D. Keromytis in Athens, Greece, in 8104476Ssam * February 2000. Network Security Technologies Inc. (NSTI) kindly 9104476Ssam * supported the development of this code. 10104476Ssam * 11104476Ssam * Copyright (c) 2000, 2001 Angelos D. Keromytis 12104476Ssam * 13104476Ssam * Permission to use, copy, and modify this software with or without fee 14104476Ssam * is hereby granted, provided that this entire notice is included in 15104476Ssam * all source code copies of any software which is or includes a copy or 16104476Ssam * modification of this software. 17104476Ssam * 18104476Ssam * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 19104476Ssam * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 20104476Ssam * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 21104476Ssam * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 22104476Ssam * PURPOSE. 23104476Ssam */ 24104476Ssam 25116191Sobrien#include <sys/cdefs.h> 26116191Sobrien__FBSDID("$FreeBSD: head/sys/opencrypto/cryptosoft.c 184205 2008-10-23 15:53:51Z des $"); 27116191Sobrien 28104476Ssam#include <sys/param.h> 29104476Ssam#include <sys/systm.h> 30104476Ssam#include <sys/malloc.h> 31104476Ssam#include <sys/mbuf.h> 32167755Ssam#include <sys/module.h> 33104476Ssam#include <sys/sysctl.h> 34104476Ssam#include <sys/errno.h> 35104476Ssam#include <sys/random.h> 36104476Ssam#include <sys/kernel.h> 37104476Ssam#include <sys/uio.h> 38104476Ssam 39104476Ssam#include <crypto/blowfish/blowfish.h> 40104476Ssam#include <crypto/sha1.h> 41104476Ssam#include <opencrypto/rmd160.h> 42143406Sume#include <opencrypto/cast.h> 43104476Ssam#include <opencrypto/skipjack.h> 44104476Ssam#include <sys/md5.h> 45104476Ssam 46104476Ssam#include <opencrypto/cryptodev.h> 47104476Ssam#include <opencrypto/cryptosoft.h> 48104476Ssam#include <opencrypto/xform.h> 49104476Ssam 50167755Ssam#include <sys/kobj.h> 51167755Ssam#include <sys/bus.h> 52167755Ssam#include "cryptodev_if.h" 53104476Ssam 54167755Ssamstatic int32_t swcr_id; 55167755Ssamstatic struct swcr_data **swcr_sessions = NULL; 56167755Ssamstatic u_int32_t swcr_sesnum; 57104476Ssam 58167755Ssamu_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN]; 59167755Ssamu_int8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN]; 60167755Ssam 61104476Ssamstatic int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); 62159242Spjdstatic int swcr_authcompute(struct cryptodesc *, struct swcr_data *, caddr_t, int); 63104476Ssamstatic int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); 64167755Ssamstatic int swcr_freesession(device_t dev, u_int64_t tid); 65104476Ssam 66104476Ssam/* 67104476Ssam * Apply a symmetric encryption/decryption algorithm. 68104476Ssam */ 69104476Ssamstatic int 70104476Ssamswcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, 71159242Spjd int flags) 72104476Ssam{ 73104476Ssam unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; 74104476Ssam unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; 75104476Ssam struct enc_xform *exf; 76104476Ssam int i, k, j, blks; 77104476Ssam 78104476Ssam exf = sw->sw_exf; 79104476Ssam blks = exf->blocksize; 80104476Ssam 81104476Ssam /* Check for non-padded data */ 82104476Ssam if (crd->crd_len % blks) 83104476Ssam return EINVAL; 84104476Ssam 85104476Ssam /* Initialize the IV */ 86104476Ssam if (crd->crd_flags & CRD_F_ENCRYPT) { 87104476Ssam /* IV explicitly provided ? */ 88104476Ssam if (crd->crd_flags & CRD_F_IV_EXPLICIT) 89104476Ssam bcopy(crd->crd_iv, iv, blks); 90157637Spjd else 91157637Spjd arc4rand(iv, blks, 0); 92104476Ssam 93104476Ssam /* Do we need to write the IV */ 94159242Spjd if (!(crd->crd_flags & CRD_F_IV_PRESENT)) 95159242Spjd crypto_copyback(flags, buf, crd->crd_inject, blks, iv); 96104476Ssam 97104476Ssam } else { /* Decryption */ 98104476Ssam /* IV explicitly provided ? */ 99104476Ssam if (crd->crd_flags & CRD_F_IV_EXPLICIT) 100104476Ssam bcopy(crd->crd_iv, iv, blks); 101104476Ssam else { 102104476Ssam /* Get IV off buf */ 103159242Spjd crypto_copydata(flags, buf, crd->crd_inject, blks, iv); 104104476Ssam } 105104476Ssam } 106104476Ssam 107125330Sphk if (crd->crd_flags & CRD_F_KEY_EXPLICIT) { 108125330Sphk int error; 109125330Sphk 110125330Sphk if (sw->sw_kschedule) 111125330Sphk exf->zerokey(&(sw->sw_kschedule)); 112125330Sphk error = exf->setkey(&sw->sw_kschedule, 113125330Sphk crd->crd_key, crd->crd_klen / 8); 114125330Sphk if (error) 115125330Sphk return (error); 116125330Sphk } 117104476Ssam ivp = iv; 118104476Ssam 119159242Spjd if (flags & CRYPTO_F_IMBUF) { 120104476Ssam struct mbuf *m = (struct mbuf *) buf; 121104476Ssam 122104476Ssam /* Find beginning of data */ 123104476Ssam m = m_getptr(m, crd->crd_skip, &k); 124104476Ssam if (m == NULL) 125104476Ssam return EINVAL; 126104476Ssam 127104476Ssam i = crd->crd_len; 128104476Ssam 129104476Ssam while (i > 0) { 130104476Ssam /* 131104476Ssam * If there's insufficient data at the end of 132104476Ssam * an mbuf, we have to do some copying. 133104476Ssam */ 134104476Ssam if (m->m_len < k + blks && m->m_len != k) { 135104476Ssam m_copydata(m, k, blks, blk); 136104476Ssam 137104476Ssam /* Actual encryption/decryption */ 138104476Ssam if (crd->crd_flags & CRD_F_ENCRYPT) { 139104476Ssam /* XOR with previous block */ 140104476Ssam for (j = 0; j < blks; j++) 141104476Ssam blk[j] ^= ivp[j]; 142104476Ssam 143104476Ssam exf->encrypt(sw->sw_kschedule, blk); 144104476Ssam 145104476Ssam /* 146104476Ssam * Keep encrypted block for XOR'ing 147104476Ssam * with next block 148104476Ssam */ 149104476Ssam bcopy(blk, iv, blks); 150104476Ssam ivp = iv; 151104476Ssam } else { /* decrypt */ 152104476Ssam /* 153104476Ssam * Keep encrypted block for XOR'ing 154104476Ssam * with next block 155104476Ssam */ 156104476Ssam if (ivp == iv) 157104476Ssam bcopy(blk, piv, blks); 158104476Ssam else 159104476Ssam bcopy(blk, iv, blks); 160104476Ssam 161104476Ssam exf->decrypt(sw->sw_kschedule, blk); 162104476Ssam 163104476Ssam /* XOR with previous block */ 164104476Ssam for (j = 0; j < blks; j++) 165104476Ssam blk[j] ^= ivp[j]; 166104476Ssam 167104476Ssam if (ivp == iv) 168104476Ssam bcopy(piv, iv, blks); 169104476Ssam else 170104476Ssam ivp = iv; 171104476Ssam } 172104476Ssam 173104476Ssam /* Copy back decrypted block */ 174104476Ssam m_copyback(m, k, blks, blk); 175104476Ssam 176104476Ssam /* Advance pointer */ 177104476Ssam m = m_getptr(m, k + blks, &k); 178104476Ssam if (m == NULL) 179104476Ssam return EINVAL; 180104476Ssam 181104476Ssam i -= blks; 182104476Ssam 183104476Ssam /* Could be done... */ 184104476Ssam if (i == 0) 185104476Ssam break; 186104476Ssam } 187104476Ssam 188104476Ssam /* Skip possibly empty mbufs */ 189104476Ssam if (k == m->m_len) { 190104476Ssam for (m = m->m_next; m && m->m_len == 0; 191104476Ssam m = m->m_next) 192104476Ssam ; 193104476Ssam k = 0; 194104476Ssam } 195104476Ssam 196104476Ssam /* Sanity check */ 197104476Ssam if (m == NULL) 198104476Ssam return EINVAL; 199104476Ssam 200104476Ssam /* 201104476Ssam * Warning: idat may point to garbage here, but 202104476Ssam * we only use it in the while() loop, only if 203104476Ssam * there are indeed enough data. 204104476Ssam */ 205104476Ssam idat = mtod(m, unsigned char *) + k; 206104476Ssam 207104476Ssam while (m->m_len >= k + blks && i > 0) { 208104476Ssam if (crd->crd_flags & CRD_F_ENCRYPT) { 209104476Ssam /* XOR with previous block/IV */ 210104476Ssam for (j = 0; j < blks; j++) 211104476Ssam idat[j] ^= ivp[j]; 212104476Ssam 213104476Ssam exf->encrypt(sw->sw_kschedule, idat); 214104476Ssam ivp = idat; 215104476Ssam } else { /* decrypt */ 216104476Ssam /* 217104476Ssam * Keep encrypted block to be used 218104476Ssam * in next block's processing. 219104476Ssam */ 220104476Ssam if (ivp == iv) 221104476Ssam bcopy(idat, piv, blks); 222104476Ssam else 223104476Ssam bcopy(idat, iv, blks); 224104476Ssam 225104476Ssam exf->decrypt(sw->sw_kschedule, idat); 226104476Ssam 227104476Ssam /* XOR with previous block/IV */ 228104476Ssam for (j = 0; j < blks; j++) 229104476Ssam idat[j] ^= ivp[j]; 230104476Ssam 231104476Ssam if (ivp == iv) 232104476Ssam bcopy(piv, iv, blks); 233104476Ssam else 234104476Ssam ivp = iv; 235104476Ssam } 236104476Ssam 237104476Ssam idat += blks; 238104476Ssam k += blks; 239104476Ssam i -= blks; 240104476Ssam } 241104476Ssam } 242104476Ssam 243104476Ssam return 0; /* Done with mbuf encryption/decryption */ 244159242Spjd } else if (flags & CRYPTO_F_IOV) { 245104476Ssam struct uio *uio = (struct uio *) buf; 246104476Ssam struct iovec *iov; 247104476Ssam 248104476Ssam /* Find beginning of data */ 249104476Ssam iov = cuio_getptr(uio, crd->crd_skip, &k); 250104476Ssam if (iov == NULL) 251104476Ssam return EINVAL; 252104476Ssam 253104476Ssam i = crd->crd_len; 254104476Ssam 255104476Ssam while (i > 0) { 256104476Ssam /* 257104476Ssam * If there's insufficient data at the end of 258104476Ssam * an iovec, we have to do some copying. 259104476Ssam */ 260104476Ssam if (iov->iov_len < k + blks && iov->iov_len != k) { 261104476Ssam cuio_copydata(uio, k, blks, blk); 262104476Ssam 263104476Ssam /* Actual encryption/decryption */ 264104476Ssam if (crd->crd_flags & CRD_F_ENCRYPT) { 265104476Ssam /* XOR with previous block */ 266104476Ssam for (j = 0; j < blks; j++) 267104476Ssam blk[j] ^= ivp[j]; 268104476Ssam 269104476Ssam exf->encrypt(sw->sw_kschedule, blk); 270104476Ssam 271104476Ssam /* 272104476Ssam * Keep encrypted block for XOR'ing 273104476Ssam * with next block 274104476Ssam */ 275104476Ssam bcopy(blk, iv, blks); 276104476Ssam ivp = iv; 277104476Ssam } else { /* decrypt */ 278104476Ssam /* 279104476Ssam * Keep encrypted block for XOR'ing 280104476Ssam * with next block 281104476Ssam */ 282104476Ssam if (ivp == iv) 283104476Ssam bcopy(blk, piv, blks); 284104476Ssam else 285104476Ssam bcopy(blk, iv, blks); 286104476Ssam 287104476Ssam exf->decrypt(sw->sw_kschedule, blk); 288104476Ssam 289104476Ssam /* XOR with previous block */ 290104476Ssam for (j = 0; j < blks; j++) 291104476Ssam blk[j] ^= ivp[j]; 292104476Ssam 293104476Ssam if (ivp == iv) 294104476Ssam bcopy(piv, iv, blks); 295104476Ssam else 296104476Ssam ivp = iv; 297104476Ssam } 298104476Ssam 299104476Ssam /* Copy back decrypted block */ 300104476Ssam cuio_copyback(uio, k, blks, blk); 301104476Ssam 302104476Ssam /* Advance pointer */ 303104476Ssam iov = cuio_getptr(uio, k + blks, &k); 304104476Ssam if (iov == NULL) 305104476Ssam return EINVAL; 306104476Ssam 307104476Ssam i -= blks; 308104476Ssam 309104476Ssam /* Could be done... */ 310104476Ssam if (i == 0) 311104476Ssam break; 312104476Ssam } 313104476Ssam 314104476Ssam /* 315104476Ssam * Warning: idat may point to garbage here, but 316104476Ssam * we only use it in the while() loop, only if 317104476Ssam * there are indeed enough data. 318104476Ssam */ 319104908Smike idat = (char *)iov->iov_base + k; 320104476Ssam 321104476Ssam while (iov->iov_len >= k + blks && i > 0) { 322104476Ssam if (crd->crd_flags & CRD_F_ENCRYPT) { 323104476Ssam /* XOR with previous block/IV */ 324104476Ssam for (j = 0; j < blks; j++) 325104476Ssam idat[j] ^= ivp[j]; 326104476Ssam 327104476Ssam exf->encrypt(sw->sw_kschedule, idat); 328104476Ssam ivp = idat; 329104476Ssam } else { /* decrypt */ 330104476Ssam /* 331104476Ssam * Keep encrypted block to be used 332104476Ssam * in next block's processing. 333104476Ssam */ 334104476Ssam if (ivp == iv) 335104476Ssam bcopy(idat, piv, blks); 336104476Ssam else 337104476Ssam bcopy(idat, iv, blks); 338104476Ssam 339104476Ssam exf->decrypt(sw->sw_kschedule, idat); 340104476Ssam 341104476Ssam /* XOR with previous block/IV */ 342104476Ssam for (j = 0; j < blks; j++) 343104476Ssam idat[j] ^= ivp[j]; 344104476Ssam 345104476Ssam if (ivp == iv) 346104476Ssam bcopy(piv, iv, blks); 347104476Ssam else 348104476Ssam ivp = iv; 349104476Ssam } 350104476Ssam 351104476Ssam idat += blks; 352104476Ssam k += blks; 353104476Ssam i -= blks; 354104476Ssam } 355104476Ssam } 356104476Ssam 357158703Spjd return 0; /* Done with iovec encryption/decryption */ 358159242Spjd } else { /* contiguous buffer */ 359159242Spjd if (crd->crd_flags & CRD_F_ENCRYPT) { 360159242Spjd for (i = crd->crd_skip; 361159242Spjd i < crd->crd_skip + crd->crd_len; i += blks) { 362159242Spjd /* XOR with the IV/previous block, as appropriate. */ 363159242Spjd if (i == crd->crd_skip) 364159242Spjd for (k = 0; k < blks; k++) 365159242Spjd buf[i + k] ^= ivp[k]; 366159242Spjd else 367159242Spjd for (k = 0; k < blks; k++) 368159242Spjd buf[i + k] ^= buf[i + k - blks]; 369159242Spjd exf->encrypt(sw->sw_kschedule, buf + i); 370159242Spjd } 371159242Spjd } else { /* Decrypt */ 372159242Spjd /* 373159242Spjd * Start at the end, so we don't need to keep the encrypted 374159242Spjd * block as the IV for the next block. 375159242Spjd */ 376159242Spjd for (i = crd->crd_skip + crd->crd_len - blks; 377159242Spjd i >= crd->crd_skip; i -= blks) { 378159242Spjd exf->decrypt(sw->sw_kschedule, buf + i); 379159242Spjd 380159242Spjd /* XOR with the IV/previous block, as appropriate */ 381159242Spjd if (i == crd->crd_skip) 382159242Spjd for (k = 0; k < blks; k++) 383159242Spjd buf[i + k] ^= ivp[k]; 384159242Spjd else 385159242Spjd for (k = 0; k < blks; k++) 386159242Spjd buf[i + k] ^= buf[i + k - blks]; 387159242Spjd } 388159242Spjd } 389159242Spjd 390159242Spjd return 0; /* Done with contiguous buffer encryption/decryption */ 391104476Ssam } 392104476Ssam 393104476Ssam /* Unreachable */ 394104476Ssam return EINVAL; 395104476Ssam} 396104476Ssam 397158703Spjdstatic void 398158703Spjdswcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key, 399158703Spjd int klen) 400158703Spjd{ 401158703Spjd int k; 402158703Spjd 403158703Spjd klen /= 8; 404158703Spjd 405158703Spjd switch (axf->type) { 406158703Spjd case CRYPTO_MD5_HMAC: 407158703Spjd case CRYPTO_SHA1_HMAC: 408158703Spjd case CRYPTO_SHA2_256_HMAC: 409158703Spjd case CRYPTO_SHA2_384_HMAC: 410158703Spjd case CRYPTO_SHA2_512_HMAC: 411158703Spjd case CRYPTO_NULL_HMAC: 412158703Spjd case CRYPTO_RIPEMD160_HMAC: 413158703Spjd for (k = 0; k < klen; k++) 414158703Spjd key[k] ^= HMAC_IPAD_VAL; 415158703Spjd 416158703Spjd axf->Init(sw->sw_ictx); 417158703Spjd axf->Update(sw->sw_ictx, key, klen); 418158703Spjd axf->Update(sw->sw_ictx, hmac_ipad_buffer, axf->blocksize - klen); 419158703Spjd 420158703Spjd for (k = 0; k < klen; k++) 421158703Spjd key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); 422158703Spjd 423158703Spjd axf->Init(sw->sw_octx); 424158703Spjd axf->Update(sw->sw_octx, key, klen); 425158703Spjd axf->Update(sw->sw_octx, hmac_opad_buffer, axf->blocksize - klen); 426158703Spjd 427158703Spjd for (k = 0; k < klen; k++) 428158703Spjd key[k] ^= HMAC_OPAD_VAL; 429158703Spjd break; 430158703Spjd case CRYPTO_MD5_KPDK: 431158703Spjd case CRYPTO_SHA1_KPDK: 432158703Spjd sw->sw_klen = klen; 433158703Spjd bcopy(key, sw->sw_octx, klen); 434158703Spjd axf->Init(sw->sw_ictx); 435158703Spjd axf->Update(sw->sw_ictx, key, klen); 436158703Spjd axf->Final(NULL, sw->sw_ictx); 437158703Spjd break; 438158703Spjd default: 439158703Spjd printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d " 440158703Spjd "doesn't use keys.\n", __func__, axf->type); 441158703Spjd } 442158703Spjd} 443158703Spjd 444104476Ssam/* 445104476Ssam * Compute keyed-hash authenticator. 446104476Ssam */ 447104476Ssamstatic int 448159223Spjdswcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, 449159242Spjd int flags) 450104476Ssam{ 451159228Spjd unsigned char aalg[HASH_MAX_LEN]; 452104476Ssam struct auth_hash *axf; 453104476Ssam union authctx ctx; 454104476Ssam int err; 455104476Ssam 456104476Ssam if (sw->sw_ictx == 0) 457104476Ssam return EINVAL; 458104476Ssam 459104476Ssam axf = sw->sw_axf; 460104476Ssam 461158703Spjd if (crd->crd_flags & CRD_F_KEY_EXPLICIT) 462158703Spjd swcr_authprepare(axf, sw, crd->crd_key, crd->crd_klen); 463158703Spjd 464104476Ssam bcopy(sw->sw_ictx, &ctx, axf->ctxsize); 465104476Ssam 466159242Spjd err = crypto_apply(flags, buf, crd->crd_skip, crd->crd_len, 467159242Spjd (int (*)(void *, void *, unsigned int))axf->Update, (caddr_t)&ctx); 468159242Spjd if (err) 469159242Spjd return err; 470104476Ssam 471104476Ssam switch (sw->sw_alg) { 472104476Ssam case CRYPTO_MD5_HMAC: 473104476Ssam case CRYPTO_SHA1_HMAC: 474158703Spjd case CRYPTO_SHA2_256_HMAC: 475158703Spjd case CRYPTO_SHA2_384_HMAC: 476158703Spjd case CRYPTO_SHA2_512_HMAC: 477104476Ssam case CRYPTO_RIPEMD160_HMAC: 478104476Ssam if (sw->sw_octx == NULL) 479104476Ssam return EINVAL; 480104476Ssam 481104476Ssam axf->Final(aalg, &ctx); 482104476Ssam bcopy(sw->sw_octx, &ctx, axf->ctxsize); 483104476Ssam axf->Update(&ctx, aalg, axf->hashsize); 484104476Ssam axf->Final(aalg, &ctx); 485104476Ssam break; 486104476Ssam 487104476Ssam case CRYPTO_MD5_KPDK: 488104476Ssam case CRYPTO_SHA1_KPDK: 489104476Ssam if (sw->sw_octx == NULL) 490104476Ssam return EINVAL; 491104476Ssam 492104476Ssam axf->Update(&ctx, sw->sw_octx, sw->sw_klen); 493104476Ssam axf->Final(aalg, &ctx); 494104476Ssam break; 495104476Ssam 496104476Ssam case CRYPTO_NULL_HMAC: 497104476Ssam axf->Final(aalg, &ctx); 498104476Ssam break; 499104476Ssam } 500104476Ssam 501104476Ssam /* Inject the authentication data */ 502159242Spjd crypto_copyback(flags, buf, crd->crd_inject, 503158703Spjd sw->sw_mlen == 0 ? axf->hashsize : sw->sw_mlen, aalg); 504104476Ssam return 0; 505104476Ssam} 506104476Ssam 507104476Ssam/* 508104476Ssam * Apply a compression/decompression algorithm 509104476Ssam */ 510104476Ssamstatic int 511104476Ssamswcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, 512159242Spjd caddr_t buf, int flags) 513104476Ssam{ 514104476Ssam u_int8_t *data, *out; 515104476Ssam struct comp_algo *cxf; 516104476Ssam int adj; 517104476Ssam u_int32_t result; 518104476Ssam 519104476Ssam cxf = sw->sw_cxf; 520104476Ssam 521104476Ssam /* We must handle the whole buffer of data in one time 522104476Ssam * then if there is not all the data in the mbuf, we must 523104476Ssam * copy in a buffer. 524104476Ssam */ 525104476Ssam 526184205Sdes data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); 527104476Ssam if (data == NULL) 528104476Ssam return (EINVAL); 529159242Spjd crypto_copydata(flags, buf, crd->crd_skip, crd->crd_len, data); 530104476Ssam 531104476Ssam if (crd->crd_flags & CRD_F_COMP) 532104476Ssam result = cxf->compress(data, crd->crd_len, &out); 533104476Ssam else 534104476Ssam result = cxf->decompress(data, crd->crd_len, &out); 535104476Ssam 536184205Sdes free(data, M_CRYPTO_DATA); 537104476Ssam if (result == 0) 538104476Ssam return EINVAL; 539104476Ssam 540104476Ssam /* Copy back the (de)compressed data. m_copyback is 541104476Ssam * extending the mbuf as necessary. 542104476Ssam */ 543104476Ssam sw->sw_size = result; 544104476Ssam /* Check the compressed size when doing compression */ 545104476Ssam if (crd->crd_flags & CRD_F_COMP) { 546104476Ssam if (result > crd->crd_len) { 547104476Ssam /* Compression was useless, we lost time */ 548184205Sdes free(out, M_CRYPTO_DATA); 549104476Ssam return 0; 550104476Ssam } 551104476Ssam } 552104476Ssam 553159242Spjd crypto_copyback(flags, buf, crd->crd_skip, result, out); 554104476Ssam if (result < crd->crd_len) { 555104476Ssam adj = result - crd->crd_len; 556159242Spjd if (flags & CRYPTO_F_IMBUF) { 557104476Ssam adj = result - crd->crd_len; 558104476Ssam m_adj((struct mbuf *)buf, adj); 559159242Spjd } else if (flags & CRYPTO_F_IOV) { 560104476Ssam struct uio *uio = (struct uio *)buf; 561104476Ssam int ind; 562104476Ssam 563104476Ssam adj = crd->crd_len - result; 564104476Ssam ind = uio->uio_iovcnt - 1; 565104476Ssam 566104476Ssam while (adj > 0 && ind >= 0) { 567104476Ssam if (adj < uio->uio_iov[ind].iov_len) { 568104476Ssam uio->uio_iov[ind].iov_len -= adj; 569104476Ssam break; 570104476Ssam } 571104476Ssam 572104476Ssam adj -= uio->uio_iov[ind].iov_len; 573104476Ssam uio->uio_iov[ind].iov_len = 0; 574104476Ssam ind--; 575104476Ssam uio->uio_iovcnt--; 576104476Ssam } 577104476Ssam } 578104476Ssam } 579184205Sdes free(out, M_CRYPTO_DATA); 580104476Ssam return 0; 581104476Ssam} 582104476Ssam 583104476Ssam/* 584104476Ssam * Generate a new software session. 585104476Ssam */ 586104476Ssamstatic int 587167755Ssamswcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) 588104476Ssam{ 589104476Ssam struct swcr_data **swd; 590104476Ssam struct auth_hash *axf; 591104476Ssam struct enc_xform *txf; 592104476Ssam struct comp_algo *cxf; 593104476Ssam u_int32_t i; 594158703Spjd int error; 595104476Ssam 596104476Ssam if (sid == NULL || cri == NULL) 597104476Ssam return EINVAL; 598104476Ssam 599104476Ssam if (swcr_sessions) { 600104476Ssam for (i = 1; i < swcr_sesnum; i++) 601104476Ssam if (swcr_sessions[i] == NULL) 602104476Ssam break; 603104476Ssam } else 604104476Ssam i = 1; /* NB: to silence compiler warning */ 605104476Ssam 606104476Ssam if (swcr_sessions == NULL || i == swcr_sesnum) { 607104476Ssam if (swcr_sessions == NULL) { 608104476Ssam i = 1; /* We leave swcr_sessions[0] empty */ 609104476Ssam swcr_sesnum = CRYPTO_SW_SESSIONS; 610104476Ssam } else 611104476Ssam swcr_sesnum *= 2; 612104476Ssam 613104476Ssam swd = malloc(swcr_sesnum * sizeof(struct swcr_data *), 614104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 615104476Ssam if (swd == NULL) { 616104476Ssam /* Reset session number */ 617104476Ssam if (swcr_sesnum == CRYPTO_SW_SESSIONS) 618104476Ssam swcr_sesnum = 0; 619104476Ssam else 620104476Ssam swcr_sesnum /= 2; 621104476Ssam return ENOBUFS; 622104476Ssam } 623104476Ssam 624104476Ssam /* Copy existing sessions */ 625167755Ssam if (swcr_sessions != NULL) { 626104476Ssam bcopy(swcr_sessions, swd, 627104476Ssam (swcr_sesnum / 2) * sizeof(struct swcr_data *)); 628104476Ssam free(swcr_sessions, M_CRYPTO_DATA); 629104476Ssam } 630104476Ssam 631104476Ssam swcr_sessions = swd; 632104476Ssam } 633104476Ssam 634104476Ssam swd = &swcr_sessions[i]; 635104476Ssam *sid = i; 636104476Ssam 637104476Ssam while (cri) { 638184205Sdes *swd = malloc(sizeof(struct swcr_data), 639104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 640104476Ssam if (*swd == NULL) { 641167755Ssam swcr_freesession(dev, i); 642104476Ssam return ENOBUFS; 643104476Ssam } 644104476Ssam 645104476Ssam switch (cri->cri_alg) { 646104476Ssam case CRYPTO_DES_CBC: 647104476Ssam txf = &enc_xform_des; 648104476Ssam goto enccommon; 649104476Ssam case CRYPTO_3DES_CBC: 650104476Ssam txf = &enc_xform_3des; 651104476Ssam goto enccommon; 652104476Ssam case CRYPTO_BLF_CBC: 653104476Ssam txf = &enc_xform_blf; 654104476Ssam goto enccommon; 655104476Ssam case CRYPTO_CAST_CBC: 656104476Ssam txf = &enc_xform_cast5; 657104476Ssam goto enccommon; 658104476Ssam case CRYPTO_SKIPJACK_CBC: 659104476Ssam txf = &enc_xform_skipjack; 660104476Ssam goto enccommon; 661104476Ssam case CRYPTO_RIJNDAEL128_CBC: 662104476Ssam txf = &enc_xform_rijndael128; 663104476Ssam goto enccommon; 664169425Sgnn case CRYPTO_CAMELLIA_CBC: 665169425Sgnn txf = &enc_xform_camellia; 666169425Sgnn goto enccommon; 667104476Ssam case CRYPTO_NULL_CBC: 668104476Ssam txf = &enc_xform_null; 669104476Ssam goto enccommon; 670104476Ssam enccommon: 671158703Spjd if (cri->cri_key != NULL) { 672158703Spjd error = txf->setkey(&((*swd)->sw_kschedule), 673158703Spjd cri->cri_key, cri->cri_klen / 8); 674158703Spjd if (error) { 675167755Ssam swcr_freesession(dev, i); 676158703Spjd return error; 677158703Spjd } 678104476Ssam } 679104476Ssam (*swd)->sw_exf = txf; 680104476Ssam break; 681104476Ssam 682104476Ssam case CRYPTO_MD5_HMAC: 683158703Spjd axf = &auth_hash_hmac_md5; 684104476Ssam goto authcommon; 685104476Ssam case CRYPTO_SHA1_HMAC: 686158703Spjd axf = &auth_hash_hmac_sha1; 687104476Ssam goto authcommon; 688158703Spjd case CRYPTO_SHA2_256_HMAC: 689158703Spjd axf = &auth_hash_hmac_sha2_256; 690104476Ssam goto authcommon; 691158703Spjd case CRYPTO_SHA2_384_HMAC: 692158703Spjd axf = &auth_hash_hmac_sha2_384; 693158703Spjd goto authcommon; 694158703Spjd case CRYPTO_SHA2_512_HMAC: 695158703Spjd axf = &auth_hash_hmac_sha2_512; 696158703Spjd goto authcommon; 697104476Ssam case CRYPTO_NULL_HMAC: 698104476Ssam axf = &auth_hash_null; 699104476Ssam goto authcommon; 700104476Ssam case CRYPTO_RIPEMD160_HMAC: 701158703Spjd axf = &auth_hash_hmac_ripemd_160; 702104476Ssam authcommon: 703104476Ssam (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 704104476Ssam M_NOWAIT); 705104476Ssam if ((*swd)->sw_ictx == NULL) { 706167755Ssam swcr_freesession(dev, i); 707104476Ssam return ENOBUFS; 708104476Ssam } 709104476Ssam 710104476Ssam (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, 711104476Ssam M_NOWAIT); 712104476Ssam if ((*swd)->sw_octx == NULL) { 713167755Ssam swcr_freesession(dev, i); 714104476Ssam return ENOBUFS; 715104476Ssam } 716158703Spjd 717158703Spjd if (cri->cri_key != NULL) { 718158703Spjd swcr_authprepare(axf, *swd, cri->cri_key, 719158703Spjd cri->cri_klen); 720158703Spjd } 721158703Spjd 722158703Spjd (*swd)->sw_mlen = cri->cri_mlen; 723104476Ssam (*swd)->sw_axf = axf; 724104476Ssam break; 725104476Ssam 726104476Ssam case CRYPTO_MD5_KPDK: 727104476Ssam axf = &auth_hash_key_md5; 728104476Ssam goto auth2common; 729104476Ssam 730104476Ssam case CRYPTO_SHA1_KPDK: 731104476Ssam axf = &auth_hash_key_sha1; 732104476Ssam auth2common: 733104476Ssam (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 734104476Ssam M_NOWAIT); 735104476Ssam if ((*swd)->sw_ictx == NULL) { 736167755Ssam swcr_freesession(dev, i); 737104476Ssam return ENOBUFS; 738104476Ssam } 739104476Ssam 740158703Spjd (*swd)->sw_octx = malloc(cri->cri_klen / 8, 741158703Spjd M_CRYPTO_DATA, M_NOWAIT); 742104476Ssam if ((*swd)->sw_octx == NULL) { 743167755Ssam swcr_freesession(dev, i); 744104476Ssam return ENOBUFS; 745104476Ssam } 746158703Spjd 747158703Spjd /* Store the key so we can "append" it to the payload */ 748158703Spjd if (cri->cri_key != NULL) { 749158703Spjd swcr_authprepare(axf, *swd, cri->cri_key, 750158703Spjd cri->cri_klen); 751158703Spjd } 752158703Spjd 753158703Spjd (*swd)->sw_mlen = cri->cri_mlen; 754104476Ssam (*swd)->sw_axf = axf; 755104476Ssam break; 756104476Ssam#ifdef notdef 757104476Ssam case CRYPTO_MD5: 758104476Ssam axf = &auth_hash_md5; 759104476Ssam goto auth3common; 760104476Ssam 761104476Ssam case CRYPTO_SHA1: 762104476Ssam axf = &auth_hash_sha1; 763104476Ssam auth3common: 764104476Ssam (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 765104476Ssam M_NOWAIT); 766104476Ssam if ((*swd)->sw_ictx == NULL) { 767167755Ssam swcr_freesession(dev, i); 768104476Ssam return ENOBUFS; 769104476Ssam } 770104476Ssam 771104476Ssam axf->Init((*swd)->sw_ictx); 772158703Spjd (*swd)->sw_mlen = cri->cri_mlen; 773104476Ssam (*swd)->sw_axf = axf; 774104476Ssam break; 775104476Ssam#endif 776104476Ssam case CRYPTO_DEFLATE_COMP: 777104476Ssam cxf = &comp_algo_deflate; 778104476Ssam (*swd)->sw_cxf = cxf; 779104476Ssam break; 780104476Ssam default: 781167755Ssam swcr_freesession(dev, i); 782104476Ssam return EINVAL; 783104476Ssam } 784104476Ssam 785104476Ssam (*swd)->sw_alg = cri->cri_alg; 786104476Ssam cri = cri->cri_next; 787104476Ssam swd = &((*swd)->sw_next); 788104476Ssam } 789104476Ssam return 0; 790104476Ssam} 791104476Ssam 792104476Ssam/* 793104476Ssam * Free a session. 794104476Ssam */ 795104476Ssamstatic int 796167755Ssamswcr_freesession(device_t dev, u_int64_t tid) 797104476Ssam{ 798104476Ssam struct swcr_data *swd; 799104476Ssam struct enc_xform *txf; 800104476Ssam struct auth_hash *axf; 801104476Ssam struct comp_algo *cxf; 802116924Ssam u_int32_t sid = CRYPTO_SESID2LID(tid); 803104476Ssam 804104476Ssam if (sid > swcr_sesnum || swcr_sessions == NULL || 805104476Ssam swcr_sessions[sid] == NULL) 806104476Ssam return EINVAL; 807104476Ssam 808104476Ssam /* Silently accept and return */ 809104476Ssam if (sid == 0) 810104476Ssam return 0; 811104476Ssam 812104476Ssam while ((swd = swcr_sessions[sid]) != NULL) { 813104476Ssam swcr_sessions[sid] = swd->sw_next; 814104476Ssam 815104476Ssam switch (swd->sw_alg) { 816104476Ssam case CRYPTO_DES_CBC: 817104476Ssam case CRYPTO_3DES_CBC: 818104476Ssam case CRYPTO_BLF_CBC: 819104476Ssam case CRYPTO_CAST_CBC: 820104476Ssam case CRYPTO_SKIPJACK_CBC: 821104476Ssam case CRYPTO_RIJNDAEL128_CBC: 822169425Sgnn case CRYPTO_CAMELLIA_CBC: 823104476Ssam case CRYPTO_NULL_CBC: 824104476Ssam txf = swd->sw_exf; 825104476Ssam 826104476Ssam if (swd->sw_kschedule) 827104476Ssam txf->zerokey(&(swd->sw_kschedule)); 828104476Ssam break; 829104476Ssam 830104476Ssam case CRYPTO_MD5_HMAC: 831104476Ssam case CRYPTO_SHA1_HMAC: 832158703Spjd case CRYPTO_SHA2_256_HMAC: 833158703Spjd case CRYPTO_SHA2_384_HMAC: 834158703Spjd case CRYPTO_SHA2_512_HMAC: 835104476Ssam case CRYPTO_RIPEMD160_HMAC: 836104476Ssam case CRYPTO_NULL_HMAC: 837104476Ssam axf = swd->sw_axf; 838104476Ssam 839104476Ssam if (swd->sw_ictx) { 840104476Ssam bzero(swd->sw_ictx, axf->ctxsize); 841104476Ssam free(swd->sw_ictx, M_CRYPTO_DATA); 842104476Ssam } 843104476Ssam if (swd->sw_octx) { 844104476Ssam bzero(swd->sw_octx, axf->ctxsize); 845104476Ssam free(swd->sw_octx, M_CRYPTO_DATA); 846104476Ssam } 847104476Ssam break; 848104476Ssam 849104476Ssam case CRYPTO_MD5_KPDK: 850104476Ssam case CRYPTO_SHA1_KPDK: 851104476Ssam axf = swd->sw_axf; 852104476Ssam 853104476Ssam if (swd->sw_ictx) { 854104476Ssam bzero(swd->sw_ictx, axf->ctxsize); 855104476Ssam free(swd->sw_ictx, M_CRYPTO_DATA); 856104476Ssam } 857104476Ssam if (swd->sw_octx) { 858104476Ssam bzero(swd->sw_octx, swd->sw_klen); 859104476Ssam free(swd->sw_octx, M_CRYPTO_DATA); 860104476Ssam } 861104476Ssam break; 862104476Ssam 863104476Ssam case CRYPTO_MD5: 864104476Ssam case CRYPTO_SHA1: 865104476Ssam axf = swd->sw_axf; 866104476Ssam 867104476Ssam if (swd->sw_ictx) 868104476Ssam free(swd->sw_ictx, M_CRYPTO_DATA); 869104476Ssam break; 870104476Ssam 871104476Ssam case CRYPTO_DEFLATE_COMP: 872104476Ssam cxf = swd->sw_cxf; 873104476Ssam break; 874104476Ssam } 875104476Ssam 876184205Sdes free(swd, M_CRYPTO_DATA); 877104476Ssam } 878104476Ssam return 0; 879104476Ssam} 880104476Ssam 881104476Ssam/* 882104476Ssam * Process a software request. 883104476Ssam */ 884104476Ssamstatic int 885167755Ssamswcr_process(device_t dev, struct cryptop *crp, int hint) 886104476Ssam{ 887104476Ssam struct cryptodesc *crd; 888104476Ssam struct swcr_data *sw; 889104476Ssam u_int32_t lid; 890104476Ssam 891104476Ssam /* Sanity check */ 892104476Ssam if (crp == NULL) 893104476Ssam return EINVAL; 894104476Ssam 895104476Ssam if (crp->crp_desc == NULL || crp->crp_buf == NULL) { 896104476Ssam crp->crp_etype = EINVAL; 897104476Ssam goto done; 898104476Ssam } 899104476Ssam 900104476Ssam lid = crp->crp_sid & 0xffffffff; 901104476Ssam if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { 902104476Ssam crp->crp_etype = ENOENT; 903104476Ssam goto done; 904104476Ssam } 905104476Ssam 906104476Ssam /* Go through crypto descriptors, processing as we go */ 907104476Ssam for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 908104476Ssam /* 909104476Ssam * Find the crypto context. 910104476Ssam * 911104476Ssam * XXX Note that the logic here prevents us from having 912104476Ssam * XXX the same algorithm multiple times in a session 913104476Ssam * XXX (or rather, we can but it won't give us the right 914104476Ssam * XXX results). To do that, we'd need some way of differentiating 915104476Ssam * XXX between the various instances of an algorithm (so we can 916104476Ssam * XXX locate the correct crypto context). 917104476Ssam */ 918104476Ssam for (sw = swcr_sessions[lid]; 919104476Ssam sw && sw->sw_alg != crd->crd_alg; 920104476Ssam sw = sw->sw_next) 921104476Ssam ; 922104476Ssam 923104476Ssam /* No such context ? */ 924104476Ssam if (sw == NULL) { 925104476Ssam crp->crp_etype = EINVAL; 926104476Ssam goto done; 927104476Ssam } 928104476Ssam switch (sw->sw_alg) { 929104476Ssam case CRYPTO_DES_CBC: 930104476Ssam case CRYPTO_3DES_CBC: 931104476Ssam case CRYPTO_BLF_CBC: 932104476Ssam case CRYPTO_CAST_CBC: 933104476Ssam case CRYPTO_SKIPJACK_CBC: 934104476Ssam case CRYPTO_RIJNDAEL128_CBC: 935169425Sgnn case CRYPTO_CAMELLIA_CBC: 936104476Ssam if ((crp->crp_etype = swcr_encdec(crd, sw, 937159242Spjd crp->crp_buf, crp->crp_flags)) != 0) 938104476Ssam goto done; 939104476Ssam break; 940104476Ssam case CRYPTO_NULL_CBC: 941104476Ssam crp->crp_etype = 0; 942104476Ssam break; 943104476Ssam case CRYPTO_MD5_HMAC: 944104476Ssam case CRYPTO_SHA1_HMAC: 945158703Spjd case CRYPTO_SHA2_256_HMAC: 946158703Spjd case CRYPTO_SHA2_384_HMAC: 947158703Spjd case CRYPTO_SHA2_512_HMAC: 948104476Ssam case CRYPTO_RIPEMD160_HMAC: 949104476Ssam case CRYPTO_NULL_HMAC: 950104476Ssam case CRYPTO_MD5_KPDK: 951104476Ssam case CRYPTO_SHA1_KPDK: 952104476Ssam case CRYPTO_MD5: 953104476Ssam case CRYPTO_SHA1: 954159223Spjd if ((crp->crp_etype = swcr_authcompute(crd, sw, 955159242Spjd crp->crp_buf, crp->crp_flags)) != 0) 956104476Ssam goto done; 957104476Ssam break; 958104476Ssam 959104476Ssam case CRYPTO_DEFLATE_COMP: 960104476Ssam if ((crp->crp_etype = swcr_compdec(crd, sw, 961159242Spjd crp->crp_buf, crp->crp_flags)) != 0) 962104476Ssam goto done; 963104476Ssam else 964104476Ssam crp->crp_olen = (int)sw->sw_size; 965104476Ssam break; 966104476Ssam 967104476Ssam default: 968104476Ssam /* Unknown/unsupported algorithm */ 969104476Ssam crp->crp_etype = EINVAL; 970104476Ssam goto done; 971104476Ssam } 972104476Ssam } 973104476Ssam 974104476Ssamdone: 975104476Ssam crypto_done(crp); 976104476Ssam return 0; 977104476Ssam} 978104476Ssam 979104476Ssamstatic void 980167755Ssamswcr_identify(device_t *dev, device_t parent) 981104476Ssam{ 982167755Ssam /* NB: order 10 is so we get attached after h/w devices */ 983167755Ssam if (device_find_child(parent, "cryptosoft", -1) == NULL && 984167755Ssam BUS_ADD_CHILD(parent, 10, "cryptosoft", -1) == 0) 985167755Ssam panic("cryptosoft: could not attach"); 986167755Ssam} 987158703Spjd 988167755Ssamstatic int 989167755Ssamswcr_probe(device_t dev) 990167755Ssam{ 991167755Ssam device_set_desc(dev, "software crypto"); 992167755Ssam return (0); 993167755Ssam} 994158703Spjd 995167755Ssamstatic int 996167755Ssamswcr_attach(device_t dev) 997167755Ssam{ 998167755Ssam memset(hmac_ipad_buffer, HMAC_IPAD_VAL, HMAC_MAX_BLOCK_LEN); 999167755Ssam memset(hmac_opad_buffer, HMAC_OPAD_VAL, HMAC_MAX_BLOCK_LEN); 1000167755Ssam 1001167755Ssam swcr_id = crypto_get_driverid(dev, 1002167755Ssam CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC); 1003167755Ssam if (swcr_id < 0) { 1004167755Ssam device_printf(dev, "cannot initialize!"); 1005167755Ssam return ENOMEM; 1006167755Ssam } 1007104476Ssam#define REGISTER(alg) \ 1008167755Ssam crypto_register(swcr_id, alg, 0,0) 1009167755Ssam REGISTER(CRYPTO_DES_CBC); 1010104476Ssam REGISTER(CRYPTO_3DES_CBC); 1011104476Ssam REGISTER(CRYPTO_BLF_CBC); 1012104476Ssam REGISTER(CRYPTO_CAST_CBC); 1013104476Ssam REGISTER(CRYPTO_SKIPJACK_CBC); 1014104476Ssam REGISTER(CRYPTO_NULL_CBC); 1015104476Ssam REGISTER(CRYPTO_MD5_HMAC); 1016104476Ssam REGISTER(CRYPTO_SHA1_HMAC); 1017158703Spjd REGISTER(CRYPTO_SHA2_256_HMAC); 1018158703Spjd REGISTER(CRYPTO_SHA2_384_HMAC); 1019158703Spjd REGISTER(CRYPTO_SHA2_512_HMAC); 1020104476Ssam REGISTER(CRYPTO_RIPEMD160_HMAC); 1021104476Ssam REGISTER(CRYPTO_NULL_HMAC); 1022104476Ssam REGISTER(CRYPTO_MD5_KPDK); 1023104476Ssam REGISTER(CRYPTO_SHA1_KPDK); 1024104476Ssam REGISTER(CRYPTO_MD5); 1025104476Ssam REGISTER(CRYPTO_SHA1); 1026104476Ssam REGISTER(CRYPTO_RIJNDAEL128_CBC); 1027169425Sgnn REGISTER(CRYPTO_CAMELLIA_CBC); 1028104476Ssam REGISTER(CRYPTO_DEFLATE_COMP); 1029104476Ssam#undef REGISTER 1030167755Ssam 1031167755Ssam return 0; 1032104476Ssam} 1033157205Spjd 1034157205Spjdstatic void 1035167755Ssamswcr_detach(device_t dev) 1036157205Spjd{ 1037167755Ssam crypto_unregister_all(swcr_id); 1038157205Spjd if (swcr_sessions != NULL) 1039184205Sdes free(swcr_sessions, M_CRYPTO_DATA); 1040157205Spjd} 1041167755Ssam 1042167755Ssamstatic device_method_t swcr_methods[] = { 1043167755Ssam DEVMETHOD(device_identify, swcr_identify), 1044167755Ssam DEVMETHOD(device_probe, swcr_probe), 1045167755Ssam DEVMETHOD(device_attach, swcr_attach), 1046167755Ssam DEVMETHOD(device_detach, swcr_detach), 1047167755Ssam 1048167755Ssam DEVMETHOD(cryptodev_newsession, swcr_newsession), 1049167755Ssam DEVMETHOD(cryptodev_freesession,swcr_freesession), 1050167755Ssam DEVMETHOD(cryptodev_process, swcr_process), 1051167755Ssam 1052167755Ssam {0, 0}, 1053167755Ssam}; 1054167755Ssam 1055167755Ssamstatic driver_t swcr_driver = { 1056167755Ssam "cryptosoft", 1057167755Ssam swcr_methods, 1058167755Ssam 0, /* NB: no softc */ 1059167755Ssam}; 1060167755Ssamstatic devclass_t swcr_devclass; 1061167755Ssam 1062167755Ssam/* 1063167755Ssam * NB: We explicitly reference the crypto module so we 1064167755Ssam * get the necessary ordering when built as a loadable 1065167755Ssam * module. This is required because we bundle the crypto 1066167755Ssam * module code together with the cryptosoft driver (otherwise 1067167755Ssam * normal module dependencies would handle things). 1068167755Ssam */ 1069167755Ssamextern int crypto_modevent(struct module *, int, void *); 1070167755Ssam/* XXX where to attach */ 1071167755SsamDRIVER_MODULE(cryptosoft, nexus, swcr_driver, swcr_devclass, crypto_modevent,0); 1072167755SsamMODULE_VERSION(cryptosoft, 1); 1073167755SsamMODULE_DEPEND(cryptosoft, crypto, 1, 1, 1); 1074