1/* $NetBSD: cryptosoft.c,v 1.64 2022/05/22 11:39:27 riastradh Exp $ */ 2/* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */ 3/* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ 4 5/* 6 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) 7 * 8 * This code was written by Angelos D. Keromytis in Athens, Greece, in 9 * February 2000. Network Security Technologies Inc. (NSTI) kindly 10 * supported the development of this code. 11 * 12 * Copyright (c) 2000, 2001 Angelos D. Keromytis 13 * 14 * Permission to use, copy, and modify this software with or without fee 15 * is hereby granted, provided that this entire notice is included in 16 * all source code copies of any software which is or includes a copy or 17 * modification of this software. 18 * 19 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 20 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 21 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 22 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 23 * PURPOSE. 24 */ 25 26#include <sys/cdefs.h> 27__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.64 2022/05/22 11:39:27 riastradh Exp $"); 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/kmem.h> 32#include <sys/mbuf.h> 33#include <sys/sysctl.h> 34#include <sys/errno.h> 35#include <sys/cprng.h> 36#include <sys/module.h> 37#include <sys/device.h> 38 39#ifdef _KERNEL_OPT 40#include "opt_ocf.h" 41#endif 42 43#include <opencrypto/cryptodev.h> 44#include <opencrypto/cryptosoft.h> 45#include <opencrypto/xform.h> 46 47#include <opencrypto/cryptosoft_xform.c> 48 49#include "ioconf.h" 50 51union authctx { 52 MD5_CTX md5ctx; 53 SHA1_CTX sha1ctx; 54 RMD160_CTX rmd160ctx; 55 SHA256_CTX sha256ctx; 56 SHA384_CTX sha384ctx; 57 SHA512_CTX sha512ctx; 58 aesxcbc_ctx aesxcbcctx; 59 AES_GMAC_CTX aesgmacctx; 60}; 61 62struct swcr_data **swcr_sessions = NULL; 63u_int32_t swcr_sesnum = 0; 64int32_t swcr_id = -1; 65 66#define COPYBACK(x, a, b, c, d) \ 67 (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \ 68 : cuio_copyback((struct uio *)a,b,c,d) 69#define COPYDATA(x, a, b, c, d) \ 70 (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \ 71 : cuio_copydata((struct uio *)a,b,c,d) 72 73static int swcr_encdec(struct cryptodesc *, const struct swcr_data *, void *, int); 74static int swcr_compdec(struct cryptodesc *, const struct swcr_data *, void *, int, int *); 75static int swcr_combined(struct cryptop *, int); 76static int swcr_process(void *, struct cryptop *, int); 77static int swcr_newsession(void *, u_int32_t *, struct cryptoini *); 78static void swcr_freesession(void *, u_int64_t); 79static void swcr_freesession_internal(struct swcr_data *); 80 81static int swcryptoattach_internal(void); 82 83/* 84 * Apply a symmetric encryption/decryption algorithm. 85 */ 86static int 87swcr_encdec(struct cryptodesc *crd, const struct swcr_data *sw, void *bufv, 88 int outtype) 89{ 90 char *buf = bufv; 91 unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; 92 unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; 93 const struct swcr_enc_xform *exf; 94 int i, k, j, blks, ivlen; 95 int count, ind; 96 97 exf = sw->sw_exf; 98 blks = exf->enc_xform->blocksize; 99 ivlen = exf->enc_xform->ivsize; 100 KASSERT(exf->reinit ? ivlen <= blks : ivlen == blks); 101 102 /* Check for non-padded data */ 103 if (crd->crd_len % blks) 104 return EINVAL; 105 106 /* Initialize the IV */ 107 if (crd->crd_flags & CRD_F_ENCRYPT) { 108 /* IV explicitly provided ? */ 109 if (crd->crd_flags & CRD_F_IV_EXPLICIT) { 110 memcpy(iv, crd->crd_iv, ivlen); 111 if (exf->reinit) 112 exf->reinit(sw->sw_kschedule, iv, 0); 113 } else if (exf->reinit) { 114 exf->reinit(sw->sw_kschedule, 0, iv); 115 } else { 116 cprng_fast(iv, EALG_MAX_BLOCK_LEN); 117 } 118 119 /* Do we need to write the IV */ 120 if (!(crd->crd_flags & CRD_F_IV_PRESENT)) { 121 COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv); 122 } 123 124 } else { /* Decryption */ 125 /* IV explicitly provided ? */ 126 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 127 memcpy(iv, crd->crd_iv, ivlen); 128 else { 129 /* Get IV off buf */ 130 COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv); 131 } 132 if (exf->reinit) 133 exf->reinit(sw->sw_kschedule, iv, 0); 134 } 135 136 ivp = iv; 137 138 if (outtype == CRYPTO_BUF_CONTIG) { 139 if (exf->reinit) { 140 for (i = crd->crd_skip; 141 i < crd->crd_skip + crd->crd_len; i += blks) { 142 if (crd->crd_flags & CRD_F_ENCRYPT) { 143 exf->encrypt(sw->sw_kschedule, buf + i); 144 } else { 145 exf->decrypt(sw->sw_kschedule, buf + i); 146 } 147 } 148 } else if (crd->crd_flags & CRD_F_ENCRYPT) { 149 for (i = crd->crd_skip; 150 i < crd->crd_skip + crd->crd_len; i += blks) { 151 /* XOR with the IV/previous block, as appropriate. */ 152 if (i == crd->crd_skip) 153 for (k = 0; k < blks; k++) 154 buf[i + k] ^= ivp[k]; 155 else 156 for (k = 0; k < blks; k++) 157 buf[i + k] ^= buf[i + k - blks]; 158 exf->encrypt(sw->sw_kschedule, buf + i); 159 } 160 } else { /* Decrypt */ 161 /* 162 * Start at the end, so we don't need to keep the encrypted 163 * block as the IV for the next block. 164 */ 165 for (i = crd->crd_skip + crd->crd_len - blks; 166 i >= crd->crd_skip; i -= blks) { 167 exf->decrypt(sw->sw_kschedule, buf + i); 168 169 /* XOR with the IV/previous block, as appropriate */ 170 if (i == crd->crd_skip) 171 for (k = 0; k < blks; k++) 172 buf[i + k] ^= ivp[k]; 173 else 174 for (k = 0; k < blks; k++) 175 buf[i + k] ^= buf[i + k - blks]; 176 } 177 } 178 179 return 0; 180 } else if (outtype == CRYPTO_BUF_MBUF) { 181 struct mbuf *m = (struct mbuf *) buf; 182 183 /* Find beginning of data */ 184 m = m_getptr(m, crd->crd_skip, &k); 185 if (m == NULL) 186 return EINVAL; 187 188 i = crd->crd_len; 189 190 while (i > 0) { 191 /* 192 * If there's insufficient data at the end of 193 * an mbuf, we have to do some copying. 194 */ 195 if (m->m_len < k + blks && m->m_len != k) { 196 m_copydata(m, k, blks, blk); 197 198 /* Actual encryption/decryption */ 199 if (exf->reinit) { 200 if (crd->crd_flags & CRD_F_ENCRYPT) { 201 exf->encrypt(sw->sw_kschedule, 202 blk); 203 } else { 204 exf->decrypt(sw->sw_kschedule, 205 blk); 206 } 207 } else if (crd->crd_flags & CRD_F_ENCRYPT) { 208 /* XOR with previous block */ 209 for (j = 0; j < blks; j++) 210 blk[j] ^= ivp[j]; 211 212 exf->encrypt(sw->sw_kschedule, blk); 213 214 /* 215 * Keep encrypted block for XOR'ing 216 * with next block 217 */ 218 memcpy(iv, blk, blks); 219 ivp = iv; 220 } else { /* decrypt */ 221 /* 222 * Keep encrypted block for XOR'ing 223 * with next block 224 */ 225 if (ivp == iv) 226 memcpy(piv, blk, blks); 227 else 228 memcpy(iv, blk, blks); 229 230 exf->decrypt(sw->sw_kschedule, blk); 231 232 /* XOR with previous block */ 233 for (j = 0; j < blks; j++) 234 blk[j] ^= ivp[j]; 235 236 if (ivp == iv) 237 memcpy(iv, piv, blks); 238 else 239 ivp = iv; 240 } 241 242 /* Copy back decrypted block */ 243 m_copyback(m, k, blks, blk); 244 245 /* Advance pointer */ 246 m = m_getptr(m, k + blks, &k); 247 if (m == NULL) 248 return EINVAL; 249 250 i -= blks; 251 252 /* Could be done... */ 253 if (i == 0) 254 break; 255 } 256 257 /* Skip possibly empty mbufs */ 258 if (k == m->m_len) { 259 for (m = m->m_next; m && m->m_len == 0; 260 m = m->m_next) 261 ; 262 k = 0; 263 } 264 265 /* Sanity check */ 266 if (m == NULL) 267 return EINVAL; 268 269 /* 270 * Warning: idat may point to garbage here, but 271 * we only use it in the while() loop, only if 272 * there are indeed enough data. 273 */ 274 idat = mtod(m, unsigned char *) + k; 275 276 while (m->m_len >= k + blks && i > 0) { 277 if (exf->reinit) { 278 if (crd->crd_flags & CRD_F_ENCRYPT) { 279 exf->encrypt(sw->sw_kschedule, 280 idat); 281 } else { 282 exf->decrypt(sw->sw_kschedule, 283 idat); 284 } 285 } else if (crd->crd_flags & CRD_F_ENCRYPT) { 286 /* XOR with previous block/IV */ 287 for (j = 0; j < blks; j++) 288 idat[j] ^= ivp[j]; 289 290 exf->encrypt(sw->sw_kschedule, idat); 291 ivp = idat; 292 } else { /* decrypt */ 293 /* 294 * Keep encrypted block to be used 295 * in next block's processing. 296 */ 297 if (ivp == iv) 298 memcpy(piv, idat, blks); 299 else 300 memcpy(iv, idat, blks); 301 302 exf->decrypt(sw->sw_kschedule, idat); 303 304 /* XOR with previous block/IV */ 305 for (j = 0; j < blks; j++) 306 idat[j] ^= ivp[j]; 307 308 if (ivp == iv) 309 memcpy(iv, piv, blks); 310 else 311 ivp = iv; 312 } 313 314 idat += blks; 315 k += blks; 316 i -= blks; 317 } 318 } 319 320 return 0; /* Done with mbuf encryption/decryption */ 321 } else if (outtype == CRYPTO_BUF_IOV) { 322 struct uio *uio = (struct uio *) buf; 323 324 /* Find beginning of data */ 325 count = crd->crd_skip; 326 ind = cuio_getptr(uio, count, &k); 327 if (ind == -1) 328 return EINVAL; 329 330 i = crd->crd_len; 331 332 while (i > 0) { 333 /* 334 * If there's insufficient data at the end, 335 * we have to do some copying. 336 */ 337 if (uio->uio_iov[ind].iov_len < k + blks && 338 uio->uio_iov[ind].iov_len != k) { 339 cuio_copydata(uio, k, blks, blk); 340 341 /* Actual encryption/decryption */ 342 if (exf->reinit) { 343 if (crd->crd_flags & CRD_F_ENCRYPT) { 344 exf->encrypt(sw->sw_kschedule, 345 blk); 346 } else { 347 exf->decrypt(sw->sw_kschedule, 348 blk); 349 } 350 } else if (crd->crd_flags & CRD_F_ENCRYPT) { 351 /* XOR with previous block */ 352 for (j = 0; j < blks; j++) 353 blk[j] ^= ivp[j]; 354 355 exf->encrypt(sw->sw_kschedule, blk); 356 357 /* 358 * Keep encrypted block for XOR'ing 359 * with next block 360 */ 361 memcpy(iv, blk, blks); 362 ivp = iv; 363 } else { /* decrypt */ 364 /* 365 * Keep encrypted block for XOR'ing 366 * with next block 367 */ 368 if (ivp == iv) 369 memcpy(piv, blk, blks); 370 else 371 memcpy(iv, blk, blks); 372 373 exf->decrypt(sw->sw_kschedule, blk); 374 375 /* XOR with previous block */ 376 for (j = 0; j < blks; j++) 377 blk[j] ^= ivp[j]; 378 379 if (ivp == iv) 380 memcpy(iv, piv, blks); 381 else 382 ivp = iv; 383 } 384 385 /* Copy back decrypted block */ 386 cuio_copyback(uio, k, blks, blk); 387 388 count += blks; 389 390 /* Advance pointer */ 391 ind = cuio_getptr(uio, count, &k); 392 if (ind == -1) 393 return (EINVAL); 394 395 i -= blks; 396 397 /* Could be done... */ 398 if (i == 0) 399 break; 400 } 401 402 /* 403 * Warning: idat may point to garbage here, but 404 * we only use it in the while() loop, only if 405 * there are indeed enough data. 406 */ 407 idat = ((char *)uio->uio_iov[ind].iov_base) + k; 408 409 while (uio->uio_iov[ind].iov_len >= k + blks && 410 i > 0) { 411 if (exf->reinit) { 412 if (crd->crd_flags & CRD_F_ENCRYPT) { 413 exf->encrypt(sw->sw_kschedule, 414 idat); 415 } else { 416 exf->decrypt(sw->sw_kschedule, 417 idat); 418 } 419 } else if (crd->crd_flags & CRD_F_ENCRYPT) { 420 /* XOR with previous block/IV */ 421 for (j = 0; j < blks; j++) 422 idat[j] ^= ivp[j]; 423 424 exf->encrypt(sw->sw_kschedule, idat); 425 ivp = idat; 426 } else { /* decrypt */ 427 /* 428 * Keep encrypted block to be used 429 * in next block's processing. 430 */ 431 if (ivp == iv) 432 memcpy(piv, idat, blks); 433 else 434 memcpy(iv, idat, blks); 435 436 exf->decrypt(sw->sw_kschedule, idat); 437 438 /* XOR with previous block/IV */ 439 for (j = 0; j < blks; j++) 440 idat[j] ^= ivp[j]; 441 442 if (ivp == iv) 443 memcpy(iv, piv, blks); 444 else 445 ivp = iv; 446 } 447 448 idat += blks; 449 count += blks; 450 k += blks; 451 i -= blks; 452 } 453 } 454 return 0; /* Done with mbuf encryption/decryption */ 455 } 456 457 /* Unreachable */ 458 return EINVAL; 459} 460 461/* 462 * Compute keyed-hash authenticator. 463 */ 464int 465swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, 466 const struct swcr_data *sw, void *buf, int outtype) 467{ 468 unsigned char aalg[AALG_MAX_RESULT_LEN]; 469 const struct swcr_auth_hash *axf; 470 union authctx ctx; 471 int err; 472 473 if (sw->sw_ictx == 0) 474 return EINVAL; 475 476 axf = sw->sw_axf; 477 478 memcpy(&ctx, sw->sw_ictx, axf->ctxsize); 479 480 switch (outtype) { 481 case CRYPTO_BUF_CONTIG: 482 axf->Update(&ctx, (char *)buf + crd->crd_skip, crd->crd_len); 483 break; 484 case CRYPTO_BUF_MBUF: 485 err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len, 486 (int (*)(void*, void *, unsigned int))(void *)axf->Update, 487 (void *) &ctx); 488 if (err) 489 return err; 490 break; 491 case CRYPTO_BUF_IOV: 492 err = cuio_apply((struct uio *) buf, crd->crd_skip, 493 crd->crd_len, 494 (int (*)(void *, void *, unsigned int))(void *)axf->Update, 495 (void *) &ctx); 496 if (err) { 497 return err; 498 } 499 break; 500 default: 501 return EINVAL; 502 } 503 504 switch (sw->sw_alg) { 505 case CRYPTO_MD5_HMAC: 506 case CRYPTO_MD5_HMAC_96: 507 case CRYPTO_SHA1_HMAC: 508 case CRYPTO_SHA1_HMAC_96: 509 case CRYPTO_SHA2_256_HMAC: 510 case CRYPTO_SHA2_384_HMAC: 511 case CRYPTO_SHA2_512_HMAC: 512 case CRYPTO_RIPEMD160_HMAC: 513 case CRYPTO_RIPEMD160_HMAC_96: 514 if (sw->sw_octx == NULL) 515 return EINVAL; 516 517 axf->Final(aalg, &ctx); 518 memcpy(&ctx, sw->sw_octx, axf->ctxsize); 519 axf->Update(&ctx, aalg, axf->auth_hash->hashsize); 520 axf->Final(aalg, &ctx); 521 break; 522 523 case CRYPTO_MD5_KPDK: 524 case CRYPTO_SHA1_KPDK: 525 if (sw->sw_octx == NULL) 526 return EINVAL; 527 528 axf->Update(&ctx, sw->sw_octx, sw->sw_klen); 529 axf->Final(aalg, &ctx); 530 break; 531 532 case CRYPTO_NULL_HMAC: 533 case CRYPTO_MD5: 534 case CRYPTO_SHA1: 535 case CRYPTO_AES_XCBC_MAC_96: 536 axf->Final(aalg, &ctx); 537 break; 538 } 539 540 /* Inject the authentication data */ 541 switch (outtype) { 542 case CRYPTO_BUF_CONTIG: 543 (void)memcpy((char *)buf + crd->crd_inject, aalg, 544 axf->auth_hash->authsize); 545 break; 546 case CRYPTO_BUF_MBUF: 547 m_copyback((struct mbuf *) buf, crd->crd_inject, 548 axf->auth_hash->authsize, aalg); 549 break; 550 case CRYPTO_BUF_IOV: 551 memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); 552 break; 553 default: 554 return EINVAL; 555 } 556 return 0; 557} 558 559/* 560 * Apply a combined encryption-authentication transformation 561 */ 562static int 563swcr_combined(struct cryptop *crp, int outtype) 564{ 565 uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))]; 566 u_char *blk = (u_char *)blkbuf; 567 u_char aalg[AALG_MAX_RESULT_LEN]; 568 u_char iv[EALG_MAX_BLOCK_LEN]; 569 union authctx ctx; 570 struct cryptodesc *crd, *crda = NULL, *crde = NULL; 571 struct swcr_data *sw, *swa, *swe = NULL; 572 const struct swcr_auth_hash *axf = NULL; 573 const struct swcr_enc_xform *exf = NULL; 574 void *buf = (void *)crp->crp_buf; 575 uint32_t *blkp; 576 int i, blksz = 0, ivlen = 0, len; 577 578 for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 579 for (sw = swcr_sessions[crp->crp_sid & 0xffffffff]; 580 sw && sw->sw_alg != crd->crd_alg; 581 sw = sw->sw_next) 582 ; 583 if (sw == NULL) 584 return (EINVAL); 585 586 switch (sw->sw_alg) { 587 case CRYPTO_AES_GCM_16: 588 case CRYPTO_AES_GMAC: 589 swe = sw; 590 crde = crd; 591 exf = swe->sw_exf; 592 ivlen = exf->enc_xform->ivsize; 593 break; 594 case CRYPTO_AES_128_GMAC: 595 case CRYPTO_AES_192_GMAC: 596 case CRYPTO_AES_256_GMAC: 597 swa = sw; 598 crda = crd; 599 axf = swa->sw_axf; 600 if (swa->sw_ictx == 0) 601 return (EINVAL); 602 memcpy(&ctx, swa->sw_ictx, axf->ctxsize); 603 blksz = axf->auth_hash->blocksize; 604 break; 605 default: 606 return (EINVAL); 607 } 608 } 609 if (crde == NULL || crda == NULL) 610 return (EINVAL); 611 if (outtype == CRYPTO_BUF_CONTIG) 612 return (EINVAL); 613 614 /* Initialize the IV */ 615 if (crde->crd_flags & CRD_F_ENCRYPT) { 616 /* IV explicitly provided ? */ 617 if (crde->crd_flags & CRD_F_IV_EXPLICIT) { 618 memcpy(iv, crde->crd_iv, ivlen); 619 if (exf->reinit) 620 exf->reinit(swe->sw_kschedule, iv, 0); 621 } else if (exf->reinit) 622 exf->reinit(swe->sw_kschedule, 0, iv); 623 else 624 cprng_fast(iv, ivlen); 625 626 /* Do we need to write the IV */ 627 if (!(crde->crd_flags & CRD_F_IV_PRESENT)) 628 COPYBACK(outtype, buf, crde->crd_inject, ivlen, iv); 629 630 } else { /* Decryption */ 631 /* IV explicitly provided ? */ 632 if (crde->crd_flags & CRD_F_IV_EXPLICIT) 633 memcpy(iv, crde->crd_iv, ivlen); 634 else { 635 /* Get IV off buf */ 636 COPYDATA(outtype, buf, crde->crd_inject, ivlen, iv); 637 } 638 if (exf->reinit) 639 exf->reinit(swe->sw_kschedule, iv, 0); 640 } 641 642 /* Supply MAC with IV */ 643 if (axf->Reinit) 644 axf->Reinit(&ctx, iv, ivlen); 645 646 /* Supply MAC with AAD */ 647 for (i = 0; i < crda->crd_len; i += blksz) { 648 len = MIN(crda->crd_len - i, blksz); 649 COPYDATA(outtype, buf, crda->crd_skip + i, len, blk); 650 axf->Update(&ctx, blk, len); 651 } 652 653 /* Do encryption/decryption with MAC */ 654 for (i = 0; i < crde->crd_len; i += blksz) { 655 len = MIN(crde->crd_len - i, blksz); 656 if (len < blksz) 657 memset(blk, 0, blksz); 658 COPYDATA(outtype, buf, crde->crd_skip + i, len, blk); 659 if (crde->crd_flags & CRD_F_ENCRYPT) { 660 exf->encrypt(swe->sw_kschedule, blk); 661 axf->Update(&ctx, blk, len); 662 } else { 663 axf->Update(&ctx, blk, len); 664 exf->decrypt(swe->sw_kschedule, blk); 665 } 666 COPYBACK(outtype, buf, crde->crd_skip + i, len, blk); 667 } 668 669 /* Do any required special finalization */ 670 switch (crda->crd_alg) { 671 case CRYPTO_AES_128_GMAC: 672 case CRYPTO_AES_192_GMAC: 673 case CRYPTO_AES_256_GMAC: 674 /* length block */ 675 memset(blk, 0, blksz); 676 blkp = (uint32_t *)blk + 1; 677 *blkp = htobe32(crda->crd_len * 8); 678 blkp = (uint32_t *)blk + 3; 679 *blkp = htobe32(crde->crd_len * 8); 680 axf->Update(&ctx, blk, blksz); 681 break; 682 } 683 684 /* Finalize MAC */ 685 axf->Final(aalg, &ctx); 686 687 /* Inject the authentication data */ 688 if (outtype == CRYPTO_BUF_MBUF) 689 COPYBACK(outtype, buf, crda->crd_inject, axf->auth_hash->authsize, aalg); 690 else 691 memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); 692 693 return (0); 694} 695 696/* 697 * Apply a compression/decompression algorithm 698 */ 699static int 700swcr_compdec(struct cryptodesc *crd, const struct swcr_data *sw, 701 void *buf, int outtype, int *res_size) 702{ 703 u_int8_t *data, *out; 704 const struct swcr_comp_algo *cxf; 705 int adj; 706 u_int32_t result; 707 708 cxf = sw->sw_cxf; 709 710 /* We must handle the whole buffer of data in one time 711 * then if there is not all the data in the mbuf, we must 712 * copy in a buffer. 713 */ 714 715 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); 716 if (data == NULL) 717 return (EINVAL); 718 COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data); 719 720 if (crd->crd_flags & CRD_F_COMP) 721 result = cxf->compress(data, crd->crd_len, &out); 722 else 723 result = cxf->decompress(data, crd->crd_len, &out, 724 *res_size); 725 726 free(data, M_CRYPTO_DATA); 727 if (result == 0) 728 return EINVAL; 729 730 /* Copy back the (de)compressed data. m_copyback is 731 * extending the mbuf as necessary. 732 */ 733 *res_size = (int)result; 734 /* Check the compressed size when doing compression */ 735 if (crd->crd_flags & CRD_F_COMP && 736 sw->sw_alg == CRYPTO_DEFLATE_COMP_NOGROW && 737 result >= crd->crd_len) { 738 /* Compression was useless, we lost time */ 739 free(out, M_CRYPTO_DATA); 740 return 0; 741 } 742 743 COPYBACK(outtype, buf, crd->crd_skip, result, out); 744 if (result < crd->crd_len) { 745 adj = result - crd->crd_len; 746 if (outtype == CRYPTO_BUF_MBUF) { 747 m_adj((struct mbuf *)buf, adj); 748 } 749 /* Don't adjust the iov_len, it breaks the kmem_free */ 750 } 751 free(out, M_CRYPTO_DATA); 752 return 0; 753} 754 755/* 756 * Generate a new software session. 757 */ 758static int 759swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) 760{ 761 struct swcr_data **swd; 762 struct swcr_data *first, *tmp; 763 const struct swcr_auth_hash *axf; 764 const struct swcr_enc_xform *txf; 765 const struct swcr_comp_algo *cxf; 766 u_int32_t i; 767 int k, error; 768 769 if (swcr_sessions) { 770 for (i = 1; i < swcr_sesnum; i++) 771 if (swcr_sessions[i] == NULL) 772 break; 773 } else 774 i = 1; /* NB: to silence compiler warning */ 775 776 if (swcr_sessions == NULL || i == swcr_sesnum) { 777 u_int32_t newnum; 778 struct swcr_data **newsessions; 779 780 if (swcr_sessions == NULL) { 781 i = 1; /* We leave swcr_sessions[0] empty */ 782 newnum = CRYPTO_SW_SESSIONS; 783 } else 784 newnum = swcr_sesnum *= 2; 785 786 newsessions = kmem_zalloc(newnum * sizeof(struct swcr_data *), 787 KM_NOSLEEP); 788 if (newsessions == NULL) { 789 return ENOBUFS; 790 } 791 792 /* Copy existing sessions */ 793 if (swcr_sessions) { 794 memcpy(newsessions, swcr_sessions, 795 swcr_sesnum * sizeof(struct swcr_data *)); 796 kmem_free(swcr_sessions, 797 swcr_sesnum * sizeof(struct swcr_data *)); 798 } 799 800 swcr_sesnum = newnum; 801 swcr_sessions = newsessions; 802 } 803 804 first = NULL; 805 swd = &tmp; 806 while (cri) { 807 *swd = kmem_zalloc(sizeof **swd, KM_NOSLEEP); 808 if (*swd == NULL) { 809 if (first != NULL) 810 swcr_freesession_internal(first); 811 return ENOBUFS; 812 } else if (first == NULL) 813 first = *swd; 814 815 switch (cri->cri_alg) { 816 case CRYPTO_DES_CBC: 817 txf = &swcr_enc_xform_des; 818 goto enccommon; 819 case CRYPTO_3DES_CBC: 820 txf = &swcr_enc_xform_3des; 821 goto enccommon; 822 case CRYPTO_BLF_CBC: 823 txf = &swcr_enc_xform_blf; 824 goto enccommon; 825 case CRYPTO_CAST_CBC: 826 txf = &swcr_enc_xform_cast5; 827 goto enccommon; 828 case CRYPTO_SKIPJACK_CBC: 829 txf = &swcr_enc_xform_skipjack; 830 goto enccommon; 831 case CRYPTO_AES_CBC: 832 txf = &swcr_enc_xform_aes; 833 goto enccommon; 834 case CRYPTO_CAMELLIA_CBC: 835 txf = &swcr_enc_xform_camellia; 836 goto enccommon; 837 case CRYPTO_AES_CTR: 838 txf = &swcr_enc_xform_aes_ctr; 839 goto enccommon; 840 case CRYPTO_AES_GCM_16: 841 txf = &swcr_enc_xform_aes_gcm; 842 goto enccommon; 843 case CRYPTO_AES_GMAC: 844 txf = &swcr_enc_xform_aes_gmac; 845 goto enccommon; 846 case CRYPTO_NULL_CBC: 847 txf = &swcr_enc_xform_null; 848 goto enccommon; 849 enccommon: 850 error = txf->setkey(&((*swd)->sw_kschedule), 851 cri->cri_key, cri->cri_klen / 8); 852 if (error) { 853 swcr_freesession_internal(first); 854 return error; 855 } 856 (*swd)->sw_exf = txf; 857 break; 858 859 case CRYPTO_MD5_HMAC: 860 axf = &swcr_auth_hash_hmac_md5; 861 goto authcommon; 862 case CRYPTO_MD5_HMAC_96: 863 axf = &swcr_auth_hash_hmac_md5_96; 864 goto authcommon; 865 case CRYPTO_SHA1_HMAC: 866 axf = &swcr_auth_hash_hmac_sha1; 867 goto authcommon; 868 case CRYPTO_SHA1_HMAC_96: 869 axf = &swcr_auth_hash_hmac_sha1_96; 870 goto authcommon; 871 case CRYPTO_SHA2_256_HMAC: 872 axf = &swcr_auth_hash_hmac_sha2_256; 873 goto authcommon; 874 case CRYPTO_SHA2_384_HMAC: 875 axf = &swcr_auth_hash_hmac_sha2_384; 876 goto authcommon; 877 case CRYPTO_SHA2_512_HMAC: 878 axf = &swcr_auth_hash_hmac_sha2_512; 879 goto authcommon; 880 case CRYPTO_NULL_HMAC: 881 axf = &swcr_auth_hash_null; 882 goto authcommon; 883 case CRYPTO_RIPEMD160_HMAC: 884 axf = &swcr_auth_hash_hmac_ripemd_160; 885 goto authcommon; 886 case CRYPTO_RIPEMD160_HMAC_96: 887 axf = &swcr_auth_hash_hmac_ripemd_160_96; 888 goto authcommon; /* leave this for safety */ 889 authcommon: 890 (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); 891 if ((*swd)->sw_ictx == NULL) { 892 swcr_freesession_internal(first); 893 return ENOBUFS; 894 } 895 896 (*swd)->sw_octx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); 897 if ((*swd)->sw_octx == NULL) { 898 swcr_freesession_internal(first); 899 return ENOBUFS; 900 } 901 902 for (k = 0; k < cri->cri_klen / 8; k++) 903 cri->cri_key[k] ^= HMAC_IPAD_VAL; 904 905 axf->Init((*swd)->sw_ictx); 906 axf->Update((*swd)->sw_ictx, cri->cri_key, 907 cri->cri_klen / 8); 908 axf->Update((*swd)->sw_ictx, hmac_ipad_buffer, 909 axf->auth_hash->blocksize - (cri->cri_klen / 8)); 910 911 for (k = 0; k < cri->cri_klen / 8; k++) 912 cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); 913 914 axf->Init((*swd)->sw_octx); 915 axf->Update((*swd)->sw_octx, cri->cri_key, 916 cri->cri_klen / 8); 917 axf->Update((*swd)->sw_octx, hmac_opad_buffer, 918 axf->auth_hash->blocksize - (cri->cri_klen / 8)); 919 920 for (k = 0; k < cri->cri_klen / 8; k++) 921 cri->cri_key[k] ^= HMAC_OPAD_VAL; 922 (*swd)->sw_axf = axf; 923 break; 924 925 case CRYPTO_MD5_KPDK: 926 axf = &swcr_auth_hash_key_md5; 927 goto auth2common; 928 929 case CRYPTO_SHA1_KPDK: { 930 unsigned char digest[SHA1_DIGEST_LENGTH]; 931 CTASSERT(SHA1_DIGEST_LENGTH >= MD5_DIGEST_LENGTH); 932 axf = &swcr_auth_hash_key_sha1; 933 auth2common: 934 (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); 935 if ((*swd)->sw_ictx == NULL) { 936 swcr_freesession_internal(first); 937 return ENOBUFS; 938 } 939 940 /* Store the key so we can "append" it to the payload */ 941 (*swd)->sw_octx = kmem_alloc(cri->cri_klen / 8, 942 KM_NOSLEEP); 943 if ((*swd)->sw_octx == NULL) { 944 swcr_freesession_internal(first); 945 return ENOBUFS; 946 } 947 948 (*swd)->sw_klen = cri->cri_klen / 8; 949 memcpy((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); 950 axf->Init((*swd)->sw_ictx); 951 axf->Update((*swd)->sw_ictx, cri->cri_key, 952 cri->cri_klen / 8); 953 axf->Final(digest, (*swd)->sw_ictx); 954 (*swd)->sw_axf = axf; 955 break; 956 } 957 958 case CRYPTO_MD5: 959 axf = &swcr_auth_hash_md5; 960 goto auth3common; 961 962 case CRYPTO_SHA1: 963 axf = &swcr_auth_hash_sha1; 964 auth3common: 965 (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); 966 if ((*swd)->sw_ictx == NULL) { 967 swcr_freesession_internal(first); 968 return ENOBUFS; 969 } 970 971 axf->Init((*swd)->sw_ictx); 972 (*swd)->sw_axf = axf; 973 break; 974 975 case CRYPTO_AES_XCBC_MAC_96: 976 axf = &swcr_auth_hash_aes_xcbc_mac; 977 goto auth4common; 978 case CRYPTO_AES_128_GMAC: 979 axf = &swcr_auth_hash_gmac_aes_128; 980 goto auth4common; 981 case CRYPTO_AES_192_GMAC: 982 axf = &swcr_auth_hash_gmac_aes_192; 983 goto auth4common; 984 case CRYPTO_AES_256_GMAC: 985 axf = &swcr_auth_hash_gmac_aes_256; 986 auth4common: 987 (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); 988 if ((*swd)->sw_ictx == NULL) { 989 swcr_freesession_internal(first); 990 return ENOBUFS; 991 } 992 axf->Init((*swd)->sw_ictx); 993 axf->Setkey((*swd)->sw_ictx, 994 cri->cri_key, cri->cri_klen / 8); 995 (*swd)->sw_axf = axf; 996 break; 997 998 case CRYPTO_DEFLATE_COMP: 999 cxf = &swcr_comp_algo_deflate; 1000 (*swd)->sw_cxf = cxf; 1001 break; 1002 1003 case CRYPTO_DEFLATE_COMP_NOGROW: 1004 cxf = &swcr_comp_algo_deflate_nogrow; 1005 (*swd)->sw_cxf = cxf; 1006 break; 1007 1008 case CRYPTO_GZIP_COMP: 1009 cxf = &swcr_comp_algo_gzip; 1010 (*swd)->sw_cxf = cxf; 1011 break; 1012 default: 1013 swcr_freesession_internal(first); 1014 return EINVAL; 1015 } 1016 1017 (*swd)->sw_alg = cri->cri_alg; 1018 cri = cri->cri_next; 1019 swd = &((*swd)->sw_next); 1020 } 1021 1022 swcr_sessions[i] = first; 1023 *sid = i; 1024 return 0; 1025} 1026 1027static void 1028swcr_freesession_internal(struct swcr_data *arg) 1029{ 1030 struct swcr_data *swd, *swd0; 1031 const struct swcr_enc_xform *txf; 1032 const struct swcr_auth_hash *axf; 1033 1034 if (arg == NULL) 1035 return; 1036 1037 swd0 = arg; 1038 while ((swd = swd0) != NULL) { 1039 swd0 = swd->sw_next; 1040 1041 switch (swd->sw_alg) { 1042 case CRYPTO_DES_CBC: 1043 case CRYPTO_3DES_CBC: 1044 case CRYPTO_BLF_CBC: 1045 case CRYPTO_CAST_CBC: 1046 case CRYPTO_SKIPJACK_CBC: 1047 case CRYPTO_AES_CBC: 1048 case CRYPTO_CAMELLIA_CBC: 1049 case CRYPTO_AES_CTR: 1050 case CRYPTO_AES_GCM_16: 1051 case CRYPTO_AES_GMAC: 1052 case CRYPTO_NULL_CBC: 1053 txf = swd->sw_exf; 1054 1055 if (swd->sw_kschedule) 1056 txf->zerokey(&(swd->sw_kschedule)); 1057 break; 1058 1059 case CRYPTO_MD5_HMAC: 1060 case CRYPTO_MD5_HMAC_96: 1061 case CRYPTO_SHA1_HMAC: 1062 case CRYPTO_SHA1_HMAC_96: 1063 case CRYPTO_SHA2_256_HMAC: 1064 case CRYPTO_SHA2_384_HMAC: 1065 case CRYPTO_SHA2_512_HMAC: 1066 case CRYPTO_RIPEMD160_HMAC: 1067 case CRYPTO_RIPEMD160_HMAC_96: 1068 case CRYPTO_NULL_HMAC: 1069 axf = swd->sw_axf; 1070 1071 if (swd->sw_ictx) { 1072 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); 1073 kmem_free(swd->sw_ictx, axf->ctxsize); 1074 } 1075 if (swd->sw_octx) { 1076 explicit_memset(swd->sw_octx, 0, axf->ctxsize); 1077 kmem_free(swd->sw_octx, axf->ctxsize); 1078 } 1079 break; 1080 1081 case CRYPTO_MD5_KPDK: 1082 case CRYPTO_SHA1_KPDK: 1083 axf = swd->sw_axf; 1084 1085 if (swd->sw_ictx) { 1086 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); 1087 kmem_free(swd->sw_ictx, axf->ctxsize); 1088 } 1089 if (swd->sw_octx) { 1090 explicit_memset(swd->sw_octx, 0, swd->sw_klen); 1091 kmem_free(swd->sw_octx, swd->sw_klen); 1092 } 1093 break; 1094 1095 case CRYPTO_MD5: 1096 case CRYPTO_SHA1: 1097 case CRYPTO_AES_XCBC_MAC_96: 1098 case CRYPTO_AES_128_GMAC: 1099 case CRYPTO_AES_192_GMAC: 1100 case CRYPTO_AES_256_GMAC: 1101 axf = swd->sw_axf; 1102 1103 if (swd->sw_ictx) { 1104 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); 1105 kmem_free(swd->sw_ictx, axf->ctxsize); 1106 } 1107 break; 1108 1109 case CRYPTO_DEFLATE_COMP: 1110 case CRYPTO_DEFLATE_COMP_NOGROW: 1111 case CRYPTO_GZIP_COMP: 1112 break; 1113 } 1114 1115 kmem_free(swd, sizeof(*swd)); 1116 } 1117} 1118 1119/* 1120 * Free a session. 1121 */ 1122static void 1123swcr_freesession(void *arg, u_int64_t tid) 1124{ 1125 struct swcr_data *swd; 1126 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; 1127 1128 KASSERTMSG(sid < swcr_sesnum, "sid=%"PRIu32" swcr_sesnum=%"PRIu32, 1129 sid, swcr_sesnum); 1130 KASSERT(swcr_sessions[sid]); 1131 1132 swd = swcr_sessions[sid]; 1133 swcr_sessions[sid] = NULL; 1134 swcr_freesession_internal(swd); 1135} 1136 1137/* 1138 * Process a software request. 1139 */ 1140static int 1141swcr_process(void *arg, struct cryptop *crp, int hint) 1142{ 1143 struct cryptodesc *crd; 1144 struct swcr_data *sw; 1145 u_int32_t lid; 1146 int type; 1147 1148 /* Sanity check */ 1149 if (crp == NULL) 1150 return EINVAL; 1151 1152 if (crp->crp_desc == NULL || crp->crp_buf == NULL) { 1153 crp->crp_etype = EINVAL; 1154 goto done; 1155 } 1156 1157 lid = crp->crp_sid & 0xffffffff; 1158 if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { 1159 crp->crp_etype = ENOENT; 1160 goto done; 1161 } 1162 1163 if (crp->crp_flags & CRYPTO_F_IMBUF) { 1164 type = CRYPTO_BUF_MBUF; 1165 } else if (crp->crp_flags & CRYPTO_F_IOV) { 1166 type = CRYPTO_BUF_IOV; 1167 } else { 1168 type = CRYPTO_BUF_CONTIG; 1169 } 1170 1171 /* Go through crypto descriptors, processing as we go */ 1172 for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 1173 /* 1174 * Find the crypto context. 1175 * 1176 * XXX Note that the logic here prevents us from having 1177 * XXX the same algorithm multiple times in a session 1178 * XXX (or rather, we can but it won't give us the right 1179 * XXX results). To do that, we'd need some way of differentiating 1180 * XXX between the various instances of an algorithm (so we can 1181 * XXX locate the correct crypto context). 1182 */ 1183 for (sw = swcr_sessions[lid]; 1184 sw && sw->sw_alg != crd->crd_alg; 1185 sw = sw->sw_next) 1186 ; 1187 1188 /* No such context ? */ 1189 if (sw == NULL) { 1190 crp->crp_etype = EINVAL; 1191 goto done; 1192 } 1193 1194 switch (sw->sw_alg) { 1195 case CRYPTO_DES_CBC: 1196 case CRYPTO_3DES_CBC: 1197 case CRYPTO_BLF_CBC: 1198 case CRYPTO_CAST_CBC: 1199 case CRYPTO_SKIPJACK_CBC: 1200 case CRYPTO_AES_CBC: 1201 case CRYPTO_CAMELLIA_CBC: 1202 case CRYPTO_AES_CTR: 1203 if ((crp->crp_etype = swcr_encdec(crd, sw, 1204 crp->crp_buf, type)) != 0) 1205 goto done; 1206 break; 1207 case CRYPTO_NULL_CBC: 1208 crp->crp_etype = 0; 1209 break; 1210 case CRYPTO_MD5_HMAC: 1211 case CRYPTO_MD5_HMAC_96: 1212 case CRYPTO_SHA1_HMAC: 1213 case CRYPTO_SHA1_HMAC_96: 1214 case CRYPTO_SHA2_256_HMAC: 1215 case CRYPTO_SHA2_384_HMAC: 1216 case CRYPTO_SHA2_512_HMAC: 1217 case CRYPTO_RIPEMD160_HMAC: 1218 case CRYPTO_RIPEMD160_HMAC_96: 1219 case CRYPTO_NULL_HMAC: 1220 case CRYPTO_MD5_KPDK: 1221 case CRYPTO_SHA1_KPDK: 1222 case CRYPTO_MD5: 1223 case CRYPTO_SHA1: 1224 case CRYPTO_AES_XCBC_MAC_96: 1225 if ((crp->crp_etype = swcr_authcompute(crp, crd, sw, 1226 crp->crp_buf, type)) != 0) 1227 goto done; 1228 break; 1229 1230 case CRYPTO_AES_GCM_16: 1231 case CRYPTO_AES_GMAC: 1232 case CRYPTO_AES_128_GMAC: 1233 case CRYPTO_AES_192_GMAC: 1234 case CRYPTO_AES_256_GMAC: 1235 crp->crp_etype = swcr_combined(crp, type); 1236 goto done; 1237 1238 case CRYPTO_DEFLATE_COMP: 1239 case CRYPTO_DEFLATE_COMP_NOGROW: 1240 case CRYPTO_GZIP_COMP: 1241 DPRINTF("compdec for %d\n", sw->sw_alg); 1242 if ((crp->crp_etype = swcr_compdec(crd, sw, 1243 crp->crp_buf, type, &crp->crp_olen)) != 0) 1244 goto done; 1245 break; 1246 1247 default: 1248 /* Unknown/unsupported algorithm */ 1249 crp->crp_etype = EINVAL; 1250 goto done; 1251 } 1252 } 1253 1254done: 1255 DPRINTF("request %p done\n", crp); 1256 crypto_done(crp); 1257 return 0; 1258} 1259 1260static void 1261swcr_init(void) 1262{ 1263 swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE); 1264 if (swcr_id < 0) { 1265 /* This should never happen */ 1266 panic("Software crypto device cannot initialize!"); 1267 } 1268 1269 crypto_register(swcr_id, CRYPTO_DES_CBC, 1270 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL); 1271#define REGISTER(alg) \ 1272 crypto_register(swcr_id, alg, 0, 0, NULL, NULL, NULL, NULL) 1273 1274 REGISTER(CRYPTO_3DES_CBC); 1275 REGISTER(CRYPTO_BLF_CBC); 1276 REGISTER(CRYPTO_CAST_CBC); 1277 REGISTER(CRYPTO_SKIPJACK_CBC); 1278 REGISTER(CRYPTO_CAMELLIA_CBC); 1279 REGISTER(CRYPTO_AES_CTR); 1280 REGISTER(CRYPTO_AES_GCM_16); 1281 REGISTER(CRYPTO_AES_GMAC); 1282 REGISTER(CRYPTO_NULL_CBC); 1283 REGISTER(CRYPTO_MD5_HMAC); 1284 REGISTER(CRYPTO_MD5_HMAC_96); 1285 REGISTER(CRYPTO_SHA1_HMAC); 1286 REGISTER(CRYPTO_SHA1_HMAC_96); 1287 REGISTER(CRYPTO_SHA2_256_HMAC); 1288 REGISTER(CRYPTO_SHA2_384_HMAC); 1289 REGISTER(CRYPTO_SHA2_512_HMAC); 1290 REGISTER(CRYPTO_RIPEMD160_HMAC); 1291 REGISTER(CRYPTO_RIPEMD160_HMAC_96); 1292 REGISTER(CRYPTO_NULL_HMAC); 1293 REGISTER(CRYPTO_MD5_KPDK); 1294 REGISTER(CRYPTO_SHA1_KPDK); 1295 REGISTER(CRYPTO_MD5); 1296 REGISTER(CRYPTO_SHA1); 1297 REGISTER(CRYPTO_AES_XCBC_MAC_96); 1298 REGISTER(CRYPTO_AES_128_GMAC); 1299 REGISTER(CRYPTO_AES_192_GMAC); 1300 REGISTER(CRYPTO_AES_256_GMAC); 1301 REGISTER(CRYPTO_AES_CBC); 1302 REGISTER(CRYPTO_DEFLATE_COMP); 1303 REGISTER(CRYPTO_DEFLATE_COMP_NOGROW); 1304 REGISTER(CRYPTO_GZIP_COMP); 1305#undef REGISTER 1306} 1307 1308 1309/* 1310 * Pseudo-device init routine for software crypto. 1311 */ 1312 1313void 1314swcryptoattach(int num) 1315{ 1316 /* 1317 * swcrypto_attach() must be called after attached cpus, because 1318 * it calls softint_establish() through below call path. 1319 * swcr_init() => crypto_get_driverid() => crypto_init() 1320 * => crypto_init0() 1321 * If softint_establish() is called before attached cpus that ncpu == 0, 1322 * the softint handler is established to CPU#0 only. 1323 * 1324 * So, swcrypto_attach() must be called from not module_init_class() 1325 * but config_finalize() when it is built as builtin module. 1326 */ 1327 swcryptoattach_internal(); 1328} 1329 1330void swcrypto_attach(device_t, device_t, void *); 1331 1332void 1333swcrypto_attach(device_t parent, device_t self, void *opaque) 1334{ 1335 1336 swcr_init(); 1337 1338 if (!pmf_device_register(self, NULL, NULL)) 1339 aprint_error_dev(self, "couldn't establish power handler\n"); 1340} 1341 1342int swcrypto_detach(device_t, int); 1343 1344int 1345swcrypto_detach(device_t self, int flag) 1346{ 1347 pmf_device_deregister(self); 1348 if (swcr_id >= 0) 1349 crypto_unregister_all(swcr_id); 1350 return 0; 1351} 1352 1353int swcrypto_match(device_t, cfdata_t, void *); 1354 1355int 1356swcrypto_match(device_t parent, cfdata_t data, void *opaque) 1357{ 1358 1359 return 1; 1360} 1361 1362MODULE(MODULE_CLASS_DRIVER, swcrypto, 1363 "opencrypto,zlib,blowfish,des,cast128,camellia,skipjack"); 1364 1365CFDRIVER_DECL(swcrypto, DV_DULL, NULL); 1366 1367CFATTACH_DECL2_NEW(swcrypto, 0, swcrypto_match, swcrypto_attach, 1368 swcrypto_detach, NULL, NULL, NULL); 1369 1370static int swcryptoloc[] = { -1, -1 }; 1371 1372static struct cfdata swcrypto_cfdata[] = { 1373 { 1374 .cf_name = "swcrypto", 1375 .cf_atname = "swcrypto", 1376 .cf_unit = 0, 1377 .cf_fstate = 0, 1378 .cf_loc = swcryptoloc, 1379 .cf_flags = 0, 1380 .cf_pspec = NULL, 1381 }, 1382 { NULL, NULL, 0, 0, NULL, 0, NULL } 1383}; 1384 1385/* 1386 * Internal attach routine. 1387 * Don't call before attached cpus. 1388 */ 1389static int 1390swcryptoattach_internal(void) 1391{ 1392 int error; 1393 1394 error = config_cfdriver_attach(&swcrypto_cd); 1395 if (error) { 1396 return error; 1397 } 1398 1399 error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); 1400 if (error) { 1401 config_cfdriver_detach(&swcrypto_cd); 1402 aprint_error("%s: unable to register cfattach\n", 1403 swcrypto_cd.cd_name); 1404 1405 return error; 1406 } 1407 1408 error = config_cfdata_attach(swcrypto_cfdata, 1); 1409 if (error) { 1410 config_cfattach_detach(swcrypto_cd.cd_name, 1411 &swcrypto_ca); 1412 config_cfdriver_detach(&swcrypto_cd); 1413 aprint_error("%s: unable to register cfdata\n", 1414 swcrypto_cd.cd_name); 1415 1416 return error; 1417 } 1418 1419 (void)config_attach_pseudo(swcrypto_cfdata); 1420 1421 return 0; 1422} 1423 1424static int 1425swcrypto_modcmd(modcmd_t cmd, void *arg) 1426{ 1427 int error = 0; 1428 1429 switch (cmd) { 1430 case MODULE_CMD_INIT: 1431#ifdef _MODULE 1432 error = swcryptoattach_internal(); 1433#endif 1434 return error; 1435 case MODULE_CMD_FINI: 1436#if 1 1437 // XXX: Need to keep track if we are in use. 1438 return ENOTTY; 1439#else 1440 error = config_cfdata_detach(swcrypto_cfdata); 1441 if (error) { 1442 return error; 1443 } 1444 1445 config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); 1446 config_cfdriver_detach(&swcrypto_cd); 1447 1448 return 0; 1449#endif 1450 default: 1451 return ENOTTY; 1452 } 1453} 1454