cryptosoft.c revision 187826
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 187826 2009-01-28 15:31:16Z bz $"); 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 } 355184477Sdfr if (k == iov->iov_len) { 356184477Sdfr iov++; 357184477Sdfr k = 0; 358184477Sdfr } 359104476Ssam } 360104476Ssam 361158703Spjd return 0; /* Done with iovec encryption/decryption */ 362159242Spjd } else { /* contiguous buffer */ 363159242Spjd if (crd->crd_flags & CRD_F_ENCRYPT) { 364159242Spjd for (i = crd->crd_skip; 365159242Spjd i < crd->crd_skip + crd->crd_len; i += blks) { 366159242Spjd /* XOR with the IV/previous block, as appropriate. */ 367159242Spjd if (i == crd->crd_skip) 368159242Spjd for (k = 0; k < blks; k++) 369159242Spjd buf[i + k] ^= ivp[k]; 370159242Spjd else 371159242Spjd for (k = 0; k < blks; k++) 372159242Spjd buf[i + k] ^= buf[i + k - blks]; 373159242Spjd exf->encrypt(sw->sw_kschedule, buf + i); 374159242Spjd } 375159242Spjd } else { /* Decrypt */ 376159242Spjd /* 377159242Spjd * Start at the end, so we don't need to keep the encrypted 378159242Spjd * block as the IV for the next block. 379159242Spjd */ 380159242Spjd for (i = crd->crd_skip + crd->crd_len - blks; 381159242Spjd i >= crd->crd_skip; i -= blks) { 382159242Spjd exf->decrypt(sw->sw_kschedule, buf + i); 383159242Spjd 384159242Spjd /* XOR with the IV/previous block, as appropriate */ 385159242Spjd if (i == crd->crd_skip) 386159242Spjd for (k = 0; k < blks; k++) 387159242Spjd buf[i + k] ^= ivp[k]; 388159242Spjd else 389159242Spjd for (k = 0; k < blks; k++) 390159242Spjd buf[i + k] ^= buf[i + k - blks]; 391159242Spjd } 392159242Spjd } 393159242Spjd 394159242Spjd return 0; /* Done with contiguous buffer encryption/decryption */ 395104476Ssam } 396104476Ssam 397104476Ssam /* Unreachable */ 398104476Ssam return EINVAL; 399104476Ssam} 400104476Ssam 401158703Spjdstatic void 402158703Spjdswcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key, 403158703Spjd int klen) 404158703Spjd{ 405158703Spjd int k; 406158703Spjd 407158703Spjd klen /= 8; 408158703Spjd 409158703Spjd switch (axf->type) { 410158703Spjd case CRYPTO_MD5_HMAC: 411158703Spjd case CRYPTO_SHA1_HMAC: 412158703Spjd case CRYPTO_SHA2_256_HMAC: 413158703Spjd case CRYPTO_SHA2_384_HMAC: 414158703Spjd case CRYPTO_SHA2_512_HMAC: 415158703Spjd case CRYPTO_NULL_HMAC: 416158703Spjd case CRYPTO_RIPEMD160_HMAC: 417158703Spjd for (k = 0; k < klen; k++) 418158703Spjd key[k] ^= HMAC_IPAD_VAL; 419158703Spjd 420158703Spjd axf->Init(sw->sw_ictx); 421158703Spjd axf->Update(sw->sw_ictx, key, klen); 422158703Spjd axf->Update(sw->sw_ictx, hmac_ipad_buffer, axf->blocksize - klen); 423158703Spjd 424158703Spjd for (k = 0; k < klen; k++) 425158703Spjd key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); 426158703Spjd 427158703Spjd axf->Init(sw->sw_octx); 428158703Spjd axf->Update(sw->sw_octx, key, klen); 429158703Spjd axf->Update(sw->sw_octx, hmac_opad_buffer, axf->blocksize - klen); 430158703Spjd 431158703Spjd for (k = 0; k < klen; k++) 432158703Spjd key[k] ^= HMAC_OPAD_VAL; 433158703Spjd break; 434158703Spjd case CRYPTO_MD5_KPDK: 435158703Spjd case CRYPTO_SHA1_KPDK: 436187826Sbz { 437187826Sbz /* We need a buffer that can hold an md5 and a sha1 result. */ 438187826Sbz u_char buf[SHA1_RESULTLEN]; 439187826Sbz 440158703Spjd sw->sw_klen = klen; 441158703Spjd bcopy(key, sw->sw_octx, klen); 442158703Spjd axf->Init(sw->sw_ictx); 443158703Spjd axf->Update(sw->sw_ictx, key, klen); 444187826Sbz axf->Final(buf, sw->sw_ictx); 445158703Spjd break; 446187826Sbz } 447158703Spjd default: 448158703Spjd printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d " 449158703Spjd "doesn't use keys.\n", __func__, axf->type); 450158703Spjd } 451158703Spjd} 452158703Spjd 453104476Ssam/* 454104476Ssam * Compute keyed-hash authenticator. 455104476Ssam */ 456104476Ssamstatic int 457159223Spjdswcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, 458159242Spjd int flags) 459104476Ssam{ 460159228Spjd unsigned char aalg[HASH_MAX_LEN]; 461104476Ssam struct auth_hash *axf; 462104476Ssam union authctx ctx; 463104476Ssam int err; 464104476Ssam 465104476Ssam if (sw->sw_ictx == 0) 466104476Ssam return EINVAL; 467104476Ssam 468104476Ssam axf = sw->sw_axf; 469104476Ssam 470158703Spjd if (crd->crd_flags & CRD_F_KEY_EXPLICIT) 471158703Spjd swcr_authprepare(axf, sw, crd->crd_key, crd->crd_klen); 472158703Spjd 473104476Ssam bcopy(sw->sw_ictx, &ctx, axf->ctxsize); 474104476Ssam 475159242Spjd err = crypto_apply(flags, buf, crd->crd_skip, crd->crd_len, 476159242Spjd (int (*)(void *, void *, unsigned int))axf->Update, (caddr_t)&ctx); 477159242Spjd if (err) 478159242Spjd return err; 479104476Ssam 480104476Ssam switch (sw->sw_alg) { 481104476Ssam case CRYPTO_MD5_HMAC: 482104476Ssam case CRYPTO_SHA1_HMAC: 483158703Spjd case CRYPTO_SHA2_256_HMAC: 484158703Spjd case CRYPTO_SHA2_384_HMAC: 485158703Spjd case CRYPTO_SHA2_512_HMAC: 486104476Ssam case CRYPTO_RIPEMD160_HMAC: 487104476Ssam if (sw->sw_octx == NULL) 488104476Ssam return EINVAL; 489104476Ssam 490104476Ssam axf->Final(aalg, &ctx); 491104476Ssam bcopy(sw->sw_octx, &ctx, axf->ctxsize); 492104476Ssam axf->Update(&ctx, aalg, axf->hashsize); 493104476Ssam axf->Final(aalg, &ctx); 494104476Ssam break; 495104476Ssam 496104476Ssam case CRYPTO_MD5_KPDK: 497104476Ssam case CRYPTO_SHA1_KPDK: 498104476Ssam if (sw->sw_octx == NULL) 499104476Ssam return EINVAL; 500104476Ssam 501104476Ssam axf->Update(&ctx, sw->sw_octx, sw->sw_klen); 502104476Ssam axf->Final(aalg, &ctx); 503104476Ssam break; 504104476Ssam 505104476Ssam case CRYPTO_NULL_HMAC: 506104476Ssam axf->Final(aalg, &ctx); 507104476Ssam break; 508104476Ssam } 509104476Ssam 510104476Ssam /* Inject the authentication data */ 511159242Spjd crypto_copyback(flags, buf, crd->crd_inject, 512158703Spjd sw->sw_mlen == 0 ? axf->hashsize : sw->sw_mlen, aalg); 513104476Ssam return 0; 514104476Ssam} 515104476Ssam 516104476Ssam/* 517104476Ssam * Apply a compression/decompression algorithm 518104476Ssam */ 519104476Ssamstatic int 520104476Ssamswcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, 521159242Spjd caddr_t buf, int flags) 522104476Ssam{ 523104476Ssam u_int8_t *data, *out; 524104476Ssam struct comp_algo *cxf; 525104476Ssam int adj; 526104476Ssam u_int32_t result; 527104476Ssam 528104476Ssam cxf = sw->sw_cxf; 529104476Ssam 530104476Ssam /* We must handle the whole buffer of data in one time 531104476Ssam * then if there is not all the data in the mbuf, we must 532104476Ssam * copy in a buffer. 533104476Ssam */ 534104476Ssam 535184205Sdes data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); 536104476Ssam if (data == NULL) 537104476Ssam return (EINVAL); 538159242Spjd crypto_copydata(flags, buf, crd->crd_skip, crd->crd_len, data); 539104476Ssam 540104476Ssam if (crd->crd_flags & CRD_F_COMP) 541104476Ssam result = cxf->compress(data, crd->crd_len, &out); 542104476Ssam else 543104476Ssam result = cxf->decompress(data, crd->crd_len, &out); 544104476Ssam 545184205Sdes free(data, M_CRYPTO_DATA); 546104476Ssam if (result == 0) 547104476Ssam return EINVAL; 548104476Ssam 549104476Ssam /* Copy back the (de)compressed data. m_copyback is 550104476Ssam * extending the mbuf as necessary. 551104476Ssam */ 552104476Ssam sw->sw_size = result; 553104476Ssam /* Check the compressed size when doing compression */ 554104476Ssam if (crd->crd_flags & CRD_F_COMP) { 555104476Ssam if (result > crd->crd_len) { 556104476Ssam /* Compression was useless, we lost time */ 557184205Sdes free(out, M_CRYPTO_DATA); 558104476Ssam return 0; 559104476Ssam } 560104476Ssam } 561104476Ssam 562159242Spjd crypto_copyback(flags, buf, crd->crd_skip, result, out); 563104476Ssam if (result < crd->crd_len) { 564104476Ssam adj = result - crd->crd_len; 565159242Spjd if (flags & CRYPTO_F_IMBUF) { 566104476Ssam adj = result - crd->crd_len; 567104476Ssam m_adj((struct mbuf *)buf, adj); 568159242Spjd } else if (flags & CRYPTO_F_IOV) { 569104476Ssam struct uio *uio = (struct uio *)buf; 570104476Ssam int ind; 571104476Ssam 572104476Ssam adj = crd->crd_len - result; 573104476Ssam ind = uio->uio_iovcnt - 1; 574104476Ssam 575104476Ssam while (adj > 0 && ind >= 0) { 576104476Ssam if (adj < uio->uio_iov[ind].iov_len) { 577104476Ssam uio->uio_iov[ind].iov_len -= adj; 578104476Ssam break; 579104476Ssam } 580104476Ssam 581104476Ssam adj -= uio->uio_iov[ind].iov_len; 582104476Ssam uio->uio_iov[ind].iov_len = 0; 583104476Ssam ind--; 584104476Ssam uio->uio_iovcnt--; 585104476Ssam } 586104476Ssam } 587104476Ssam } 588184205Sdes free(out, M_CRYPTO_DATA); 589104476Ssam return 0; 590104476Ssam} 591104476Ssam 592104476Ssam/* 593104476Ssam * Generate a new software session. 594104476Ssam */ 595104476Ssamstatic int 596167755Ssamswcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) 597104476Ssam{ 598104476Ssam struct swcr_data **swd; 599104476Ssam struct auth_hash *axf; 600104476Ssam struct enc_xform *txf; 601104476Ssam struct comp_algo *cxf; 602104476Ssam u_int32_t i; 603158703Spjd int error; 604104476Ssam 605104476Ssam if (sid == NULL || cri == NULL) 606104476Ssam return EINVAL; 607104476Ssam 608104476Ssam if (swcr_sessions) { 609104476Ssam for (i = 1; i < swcr_sesnum; i++) 610104476Ssam if (swcr_sessions[i] == NULL) 611104476Ssam break; 612104476Ssam } else 613104476Ssam i = 1; /* NB: to silence compiler warning */ 614104476Ssam 615104476Ssam if (swcr_sessions == NULL || i == swcr_sesnum) { 616104476Ssam if (swcr_sessions == NULL) { 617104476Ssam i = 1; /* We leave swcr_sessions[0] empty */ 618104476Ssam swcr_sesnum = CRYPTO_SW_SESSIONS; 619104476Ssam } else 620104476Ssam swcr_sesnum *= 2; 621104476Ssam 622104476Ssam swd = malloc(swcr_sesnum * sizeof(struct swcr_data *), 623104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 624104476Ssam if (swd == NULL) { 625104476Ssam /* Reset session number */ 626104476Ssam if (swcr_sesnum == CRYPTO_SW_SESSIONS) 627104476Ssam swcr_sesnum = 0; 628104476Ssam else 629104476Ssam swcr_sesnum /= 2; 630104476Ssam return ENOBUFS; 631104476Ssam } 632104476Ssam 633104476Ssam /* Copy existing sessions */ 634167755Ssam if (swcr_sessions != NULL) { 635104476Ssam bcopy(swcr_sessions, swd, 636104476Ssam (swcr_sesnum / 2) * sizeof(struct swcr_data *)); 637104476Ssam free(swcr_sessions, M_CRYPTO_DATA); 638104476Ssam } 639104476Ssam 640104476Ssam swcr_sessions = swd; 641104476Ssam } 642104476Ssam 643104476Ssam swd = &swcr_sessions[i]; 644104476Ssam *sid = i; 645104476Ssam 646104476Ssam while (cri) { 647184205Sdes *swd = malloc(sizeof(struct swcr_data), 648104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 649104476Ssam if (*swd == NULL) { 650167755Ssam swcr_freesession(dev, i); 651104476Ssam return ENOBUFS; 652104476Ssam } 653104476Ssam 654104476Ssam switch (cri->cri_alg) { 655104476Ssam case CRYPTO_DES_CBC: 656104476Ssam txf = &enc_xform_des; 657104476Ssam goto enccommon; 658104476Ssam case CRYPTO_3DES_CBC: 659104476Ssam txf = &enc_xform_3des; 660104476Ssam goto enccommon; 661104476Ssam case CRYPTO_BLF_CBC: 662104476Ssam txf = &enc_xform_blf; 663104476Ssam goto enccommon; 664104476Ssam case CRYPTO_CAST_CBC: 665104476Ssam txf = &enc_xform_cast5; 666104476Ssam goto enccommon; 667104476Ssam case CRYPTO_SKIPJACK_CBC: 668104476Ssam txf = &enc_xform_skipjack; 669104476Ssam goto enccommon; 670104476Ssam case CRYPTO_RIJNDAEL128_CBC: 671104476Ssam txf = &enc_xform_rijndael128; 672104476Ssam goto enccommon; 673169425Sgnn case CRYPTO_CAMELLIA_CBC: 674169425Sgnn txf = &enc_xform_camellia; 675169425Sgnn goto enccommon; 676104476Ssam case CRYPTO_NULL_CBC: 677104476Ssam txf = &enc_xform_null; 678104476Ssam goto enccommon; 679104476Ssam enccommon: 680158703Spjd if (cri->cri_key != NULL) { 681158703Spjd error = txf->setkey(&((*swd)->sw_kschedule), 682158703Spjd cri->cri_key, cri->cri_klen / 8); 683158703Spjd if (error) { 684167755Ssam swcr_freesession(dev, i); 685158703Spjd return error; 686158703Spjd } 687104476Ssam } 688104476Ssam (*swd)->sw_exf = txf; 689104476Ssam break; 690104476Ssam 691104476Ssam case CRYPTO_MD5_HMAC: 692158703Spjd axf = &auth_hash_hmac_md5; 693104476Ssam goto authcommon; 694104476Ssam case CRYPTO_SHA1_HMAC: 695158703Spjd axf = &auth_hash_hmac_sha1; 696104476Ssam goto authcommon; 697158703Spjd case CRYPTO_SHA2_256_HMAC: 698158703Spjd axf = &auth_hash_hmac_sha2_256; 699104476Ssam goto authcommon; 700158703Spjd case CRYPTO_SHA2_384_HMAC: 701158703Spjd axf = &auth_hash_hmac_sha2_384; 702158703Spjd goto authcommon; 703158703Spjd case CRYPTO_SHA2_512_HMAC: 704158703Spjd axf = &auth_hash_hmac_sha2_512; 705158703Spjd goto authcommon; 706104476Ssam case CRYPTO_NULL_HMAC: 707104476Ssam axf = &auth_hash_null; 708104476Ssam goto authcommon; 709104476Ssam case CRYPTO_RIPEMD160_HMAC: 710158703Spjd axf = &auth_hash_hmac_ripemd_160; 711104476Ssam authcommon: 712104476Ssam (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 713104476Ssam M_NOWAIT); 714104476Ssam if ((*swd)->sw_ictx == NULL) { 715167755Ssam swcr_freesession(dev, i); 716104476Ssam return ENOBUFS; 717104476Ssam } 718104476Ssam 719104476Ssam (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, 720104476Ssam M_NOWAIT); 721104476Ssam if ((*swd)->sw_octx == NULL) { 722167755Ssam swcr_freesession(dev, i); 723104476Ssam return ENOBUFS; 724104476Ssam } 725158703Spjd 726158703Spjd if (cri->cri_key != NULL) { 727158703Spjd swcr_authprepare(axf, *swd, cri->cri_key, 728158703Spjd cri->cri_klen); 729158703Spjd } 730158703Spjd 731158703Spjd (*swd)->sw_mlen = cri->cri_mlen; 732104476Ssam (*swd)->sw_axf = axf; 733104476Ssam break; 734104476Ssam 735104476Ssam case CRYPTO_MD5_KPDK: 736104476Ssam axf = &auth_hash_key_md5; 737104476Ssam goto auth2common; 738104476Ssam 739104476Ssam case CRYPTO_SHA1_KPDK: 740104476Ssam axf = &auth_hash_key_sha1; 741104476Ssam auth2common: 742104476Ssam (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 743104476Ssam M_NOWAIT); 744104476Ssam if ((*swd)->sw_ictx == NULL) { 745167755Ssam swcr_freesession(dev, i); 746104476Ssam return ENOBUFS; 747104476Ssam } 748104476Ssam 749158703Spjd (*swd)->sw_octx = malloc(cri->cri_klen / 8, 750158703Spjd M_CRYPTO_DATA, M_NOWAIT); 751104476Ssam if ((*swd)->sw_octx == NULL) { 752167755Ssam swcr_freesession(dev, i); 753104476Ssam return ENOBUFS; 754104476Ssam } 755158703Spjd 756158703Spjd /* Store the key so we can "append" it to the payload */ 757158703Spjd if (cri->cri_key != NULL) { 758158703Spjd swcr_authprepare(axf, *swd, cri->cri_key, 759158703Spjd cri->cri_klen); 760158703Spjd } 761158703Spjd 762158703Spjd (*swd)->sw_mlen = cri->cri_mlen; 763104476Ssam (*swd)->sw_axf = axf; 764104476Ssam break; 765104476Ssam#ifdef notdef 766104476Ssam case CRYPTO_MD5: 767104476Ssam axf = &auth_hash_md5; 768104476Ssam goto auth3common; 769104476Ssam 770104476Ssam case CRYPTO_SHA1: 771104476Ssam axf = &auth_hash_sha1; 772104476Ssam auth3common: 773104476Ssam (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 774104476Ssam M_NOWAIT); 775104476Ssam if ((*swd)->sw_ictx == NULL) { 776167755Ssam swcr_freesession(dev, i); 777104476Ssam return ENOBUFS; 778104476Ssam } 779104476Ssam 780104476Ssam axf->Init((*swd)->sw_ictx); 781158703Spjd (*swd)->sw_mlen = cri->cri_mlen; 782104476Ssam (*swd)->sw_axf = axf; 783104476Ssam break; 784104476Ssam#endif 785104476Ssam case CRYPTO_DEFLATE_COMP: 786104476Ssam cxf = &comp_algo_deflate; 787104476Ssam (*swd)->sw_cxf = cxf; 788104476Ssam break; 789104476Ssam default: 790167755Ssam swcr_freesession(dev, i); 791104476Ssam return EINVAL; 792104476Ssam } 793104476Ssam 794104476Ssam (*swd)->sw_alg = cri->cri_alg; 795104476Ssam cri = cri->cri_next; 796104476Ssam swd = &((*swd)->sw_next); 797104476Ssam } 798104476Ssam return 0; 799104476Ssam} 800104476Ssam 801104476Ssam/* 802104476Ssam * Free a session. 803104476Ssam */ 804104476Ssamstatic int 805167755Ssamswcr_freesession(device_t dev, u_int64_t tid) 806104476Ssam{ 807104476Ssam struct swcr_data *swd; 808104476Ssam struct enc_xform *txf; 809104476Ssam struct auth_hash *axf; 810104476Ssam struct comp_algo *cxf; 811116924Ssam u_int32_t sid = CRYPTO_SESID2LID(tid); 812104476Ssam 813104476Ssam if (sid > swcr_sesnum || swcr_sessions == NULL || 814104476Ssam swcr_sessions[sid] == NULL) 815104476Ssam return EINVAL; 816104476Ssam 817104476Ssam /* Silently accept and return */ 818104476Ssam if (sid == 0) 819104476Ssam return 0; 820104476Ssam 821104476Ssam while ((swd = swcr_sessions[sid]) != NULL) { 822104476Ssam swcr_sessions[sid] = swd->sw_next; 823104476Ssam 824104476Ssam switch (swd->sw_alg) { 825104476Ssam case CRYPTO_DES_CBC: 826104476Ssam case CRYPTO_3DES_CBC: 827104476Ssam case CRYPTO_BLF_CBC: 828104476Ssam case CRYPTO_CAST_CBC: 829104476Ssam case CRYPTO_SKIPJACK_CBC: 830104476Ssam case CRYPTO_RIJNDAEL128_CBC: 831169425Sgnn case CRYPTO_CAMELLIA_CBC: 832104476Ssam case CRYPTO_NULL_CBC: 833104476Ssam txf = swd->sw_exf; 834104476Ssam 835104476Ssam if (swd->sw_kschedule) 836104476Ssam txf->zerokey(&(swd->sw_kschedule)); 837104476Ssam break; 838104476Ssam 839104476Ssam case CRYPTO_MD5_HMAC: 840104476Ssam case CRYPTO_SHA1_HMAC: 841158703Spjd case CRYPTO_SHA2_256_HMAC: 842158703Spjd case CRYPTO_SHA2_384_HMAC: 843158703Spjd case CRYPTO_SHA2_512_HMAC: 844104476Ssam case CRYPTO_RIPEMD160_HMAC: 845104476Ssam case CRYPTO_NULL_HMAC: 846104476Ssam axf = swd->sw_axf; 847104476Ssam 848104476Ssam if (swd->sw_ictx) { 849104476Ssam bzero(swd->sw_ictx, axf->ctxsize); 850104476Ssam free(swd->sw_ictx, M_CRYPTO_DATA); 851104476Ssam } 852104476Ssam if (swd->sw_octx) { 853104476Ssam bzero(swd->sw_octx, axf->ctxsize); 854104476Ssam free(swd->sw_octx, M_CRYPTO_DATA); 855104476Ssam } 856104476Ssam break; 857104476Ssam 858104476Ssam case CRYPTO_MD5_KPDK: 859104476Ssam case CRYPTO_SHA1_KPDK: 860104476Ssam axf = swd->sw_axf; 861104476Ssam 862104476Ssam if (swd->sw_ictx) { 863104476Ssam bzero(swd->sw_ictx, axf->ctxsize); 864104476Ssam free(swd->sw_ictx, M_CRYPTO_DATA); 865104476Ssam } 866104476Ssam if (swd->sw_octx) { 867104476Ssam bzero(swd->sw_octx, swd->sw_klen); 868104476Ssam free(swd->sw_octx, M_CRYPTO_DATA); 869104476Ssam } 870104476Ssam break; 871104476Ssam 872104476Ssam case CRYPTO_MD5: 873104476Ssam case CRYPTO_SHA1: 874104476Ssam axf = swd->sw_axf; 875104476Ssam 876104476Ssam if (swd->sw_ictx) 877104476Ssam free(swd->sw_ictx, M_CRYPTO_DATA); 878104476Ssam break; 879104476Ssam 880104476Ssam case CRYPTO_DEFLATE_COMP: 881104476Ssam cxf = swd->sw_cxf; 882104476Ssam break; 883104476Ssam } 884104476Ssam 885184205Sdes free(swd, M_CRYPTO_DATA); 886104476Ssam } 887104476Ssam return 0; 888104476Ssam} 889104476Ssam 890104476Ssam/* 891104476Ssam * Process a software request. 892104476Ssam */ 893104476Ssamstatic int 894167755Ssamswcr_process(device_t dev, struct cryptop *crp, int hint) 895104476Ssam{ 896104476Ssam struct cryptodesc *crd; 897104476Ssam struct swcr_data *sw; 898104476Ssam u_int32_t lid; 899104476Ssam 900104476Ssam /* Sanity check */ 901104476Ssam if (crp == NULL) 902104476Ssam return EINVAL; 903104476Ssam 904104476Ssam if (crp->crp_desc == NULL || crp->crp_buf == NULL) { 905104476Ssam crp->crp_etype = EINVAL; 906104476Ssam goto done; 907104476Ssam } 908104476Ssam 909104476Ssam lid = crp->crp_sid & 0xffffffff; 910104476Ssam if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { 911104476Ssam crp->crp_etype = ENOENT; 912104476Ssam goto done; 913104476Ssam } 914104476Ssam 915104476Ssam /* Go through crypto descriptors, processing as we go */ 916104476Ssam for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 917104476Ssam /* 918104476Ssam * Find the crypto context. 919104476Ssam * 920104476Ssam * XXX Note that the logic here prevents us from having 921104476Ssam * XXX the same algorithm multiple times in a session 922104476Ssam * XXX (or rather, we can but it won't give us the right 923104476Ssam * XXX results). To do that, we'd need some way of differentiating 924104476Ssam * XXX between the various instances of an algorithm (so we can 925104476Ssam * XXX locate the correct crypto context). 926104476Ssam */ 927104476Ssam for (sw = swcr_sessions[lid]; 928104476Ssam sw && sw->sw_alg != crd->crd_alg; 929104476Ssam sw = sw->sw_next) 930104476Ssam ; 931104476Ssam 932104476Ssam /* No such context ? */ 933104476Ssam if (sw == NULL) { 934104476Ssam crp->crp_etype = EINVAL; 935104476Ssam goto done; 936104476Ssam } 937104476Ssam switch (sw->sw_alg) { 938104476Ssam case CRYPTO_DES_CBC: 939104476Ssam case CRYPTO_3DES_CBC: 940104476Ssam case CRYPTO_BLF_CBC: 941104476Ssam case CRYPTO_CAST_CBC: 942104476Ssam case CRYPTO_SKIPJACK_CBC: 943104476Ssam case CRYPTO_RIJNDAEL128_CBC: 944169425Sgnn case CRYPTO_CAMELLIA_CBC: 945104476Ssam if ((crp->crp_etype = swcr_encdec(crd, sw, 946159242Spjd crp->crp_buf, crp->crp_flags)) != 0) 947104476Ssam goto done; 948104476Ssam break; 949104476Ssam case CRYPTO_NULL_CBC: 950104476Ssam crp->crp_etype = 0; 951104476Ssam break; 952104476Ssam case CRYPTO_MD5_HMAC: 953104476Ssam case CRYPTO_SHA1_HMAC: 954158703Spjd case CRYPTO_SHA2_256_HMAC: 955158703Spjd case CRYPTO_SHA2_384_HMAC: 956158703Spjd case CRYPTO_SHA2_512_HMAC: 957104476Ssam case CRYPTO_RIPEMD160_HMAC: 958104476Ssam case CRYPTO_NULL_HMAC: 959104476Ssam case CRYPTO_MD5_KPDK: 960104476Ssam case CRYPTO_SHA1_KPDK: 961104476Ssam case CRYPTO_MD5: 962104476Ssam case CRYPTO_SHA1: 963159223Spjd if ((crp->crp_etype = swcr_authcompute(crd, sw, 964159242Spjd crp->crp_buf, crp->crp_flags)) != 0) 965104476Ssam goto done; 966104476Ssam break; 967104476Ssam 968104476Ssam case CRYPTO_DEFLATE_COMP: 969104476Ssam if ((crp->crp_etype = swcr_compdec(crd, sw, 970159242Spjd crp->crp_buf, crp->crp_flags)) != 0) 971104476Ssam goto done; 972104476Ssam else 973104476Ssam crp->crp_olen = (int)sw->sw_size; 974104476Ssam break; 975104476Ssam 976104476Ssam default: 977104476Ssam /* Unknown/unsupported algorithm */ 978104476Ssam crp->crp_etype = EINVAL; 979104476Ssam goto done; 980104476Ssam } 981104476Ssam } 982104476Ssam 983104476Ssamdone: 984104476Ssam crypto_done(crp); 985104476Ssam return 0; 986104476Ssam} 987104476Ssam 988104476Ssamstatic void 989167755Ssamswcr_identify(device_t *dev, device_t parent) 990104476Ssam{ 991167755Ssam /* NB: order 10 is so we get attached after h/w devices */ 992167755Ssam if (device_find_child(parent, "cryptosoft", -1) == NULL && 993167755Ssam BUS_ADD_CHILD(parent, 10, "cryptosoft", -1) == 0) 994167755Ssam panic("cryptosoft: could not attach"); 995167755Ssam} 996158703Spjd 997167755Ssamstatic int 998167755Ssamswcr_probe(device_t dev) 999167755Ssam{ 1000167755Ssam device_set_desc(dev, "software crypto"); 1001167755Ssam return (0); 1002167755Ssam} 1003158703Spjd 1004167755Ssamstatic int 1005167755Ssamswcr_attach(device_t dev) 1006167755Ssam{ 1007167755Ssam memset(hmac_ipad_buffer, HMAC_IPAD_VAL, HMAC_MAX_BLOCK_LEN); 1008167755Ssam memset(hmac_opad_buffer, HMAC_OPAD_VAL, HMAC_MAX_BLOCK_LEN); 1009167755Ssam 1010167755Ssam swcr_id = crypto_get_driverid(dev, 1011167755Ssam CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC); 1012167755Ssam if (swcr_id < 0) { 1013167755Ssam device_printf(dev, "cannot initialize!"); 1014167755Ssam return ENOMEM; 1015167755Ssam } 1016104476Ssam#define REGISTER(alg) \ 1017167755Ssam crypto_register(swcr_id, alg, 0,0) 1018167755Ssam REGISTER(CRYPTO_DES_CBC); 1019104476Ssam REGISTER(CRYPTO_3DES_CBC); 1020104476Ssam REGISTER(CRYPTO_BLF_CBC); 1021104476Ssam REGISTER(CRYPTO_CAST_CBC); 1022104476Ssam REGISTER(CRYPTO_SKIPJACK_CBC); 1023104476Ssam REGISTER(CRYPTO_NULL_CBC); 1024104476Ssam REGISTER(CRYPTO_MD5_HMAC); 1025104476Ssam REGISTER(CRYPTO_SHA1_HMAC); 1026158703Spjd REGISTER(CRYPTO_SHA2_256_HMAC); 1027158703Spjd REGISTER(CRYPTO_SHA2_384_HMAC); 1028158703Spjd REGISTER(CRYPTO_SHA2_512_HMAC); 1029104476Ssam REGISTER(CRYPTO_RIPEMD160_HMAC); 1030104476Ssam REGISTER(CRYPTO_NULL_HMAC); 1031104476Ssam REGISTER(CRYPTO_MD5_KPDK); 1032104476Ssam REGISTER(CRYPTO_SHA1_KPDK); 1033104476Ssam REGISTER(CRYPTO_MD5); 1034104476Ssam REGISTER(CRYPTO_SHA1); 1035104476Ssam REGISTER(CRYPTO_RIJNDAEL128_CBC); 1036169425Sgnn REGISTER(CRYPTO_CAMELLIA_CBC); 1037104476Ssam REGISTER(CRYPTO_DEFLATE_COMP); 1038104476Ssam#undef REGISTER 1039167755Ssam 1040167755Ssam return 0; 1041104476Ssam} 1042157205Spjd 1043157205Spjdstatic void 1044167755Ssamswcr_detach(device_t dev) 1045157205Spjd{ 1046167755Ssam crypto_unregister_all(swcr_id); 1047157205Spjd if (swcr_sessions != NULL) 1048184205Sdes free(swcr_sessions, M_CRYPTO_DATA); 1049157205Spjd} 1050167755Ssam 1051167755Ssamstatic device_method_t swcr_methods[] = { 1052167755Ssam DEVMETHOD(device_identify, swcr_identify), 1053167755Ssam DEVMETHOD(device_probe, swcr_probe), 1054167755Ssam DEVMETHOD(device_attach, swcr_attach), 1055167755Ssam DEVMETHOD(device_detach, swcr_detach), 1056167755Ssam 1057167755Ssam DEVMETHOD(cryptodev_newsession, swcr_newsession), 1058167755Ssam DEVMETHOD(cryptodev_freesession,swcr_freesession), 1059167755Ssam DEVMETHOD(cryptodev_process, swcr_process), 1060167755Ssam 1061167755Ssam {0, 0}, 1062167755Ssam}; 1063167755Ssam 1064167755Ssamstatic driver_t swcr_driver = { 1065167755Ssam "cryptosoft", 1066167755Ssam swcr_methods, 1067167755Ssam 0, /* NB: no softc */ 1068167755Ssam}; 1069167755Ssamstatic devclass_t swcr_devclass; 1070167755Ssam 1071167755Ssam/* 1072167755Ssam * NB: We explicitly reference the crypto module so we 1073167755Ssam * get the necessary ordering when built as a loadable 1074167755Ssam * module. This is required because we bundle the crypto 1075167755Ssam * module code together with the cryptosoft driver (otherwise 1076167755Ssam * normal module dependencies would handle things). 1077167755Ssam */ 1078167755Ssamextern int crypto_modevent(struct module *, int, void *); 1079167755Ssam/* XXX where to attach */ 1080167755SsamDRIVER_MODULE(cryptosoft, nexus, swcr_driver, swcr_devclass, crypto_modevent,0); 1081167755SsamMODULE_VERSION(cryptosoft, 1); 1082167755SsamMODULE_DEPEND(cryptosoft, crypto, 1, 1, 1); 1083