1 /* $NetBSD: cryptosoft.c,v 1.5 2003/07/30 18:20:16 jonathan 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.5 2003/07/30 18:20:16 jonathan Exp $"); 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/malloc.h> 32 #include <sys/mbuf.h> 33 #include <sys/sysctl.h> 34 #include <sys/errno.h> 35 #include <sys/md5.h> 36 #include <sys/sha1.h> 37 38 #include <opencrypto/rmd160.h> 39 #include <opencrypto/cast.h> 40 #include <opencrypto/skipjack.h> 41 #include <opencrypto/blf.h> 42 #include <opencrypto/cryptodev.h> 43 #include <opencrypto/cryptosoft.h> 44 #include <opencrypto/xform.h> 45 46 u_int8_t hmac_ipad_buffer[64] = { 47 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 48 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 49 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 50 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 51 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 52 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 53 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 54 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 55 }; 56 57 u_int8_t hmac_opad_buffer[64] = { 58 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 59 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 60 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 61 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 62 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 63 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 64 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 65 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C 66 }; 67 68 69 struct swcr_data **swcr_sessions = NULL; 70 u_int32_t swcr_sesnum = 0; 71 int32_t swcr_id = -1; 72 73 #define COPYBACK(x, a, b, c, d) \ 74 (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \ 75 : cuio_copyback((struct uio *)a,b,c,d) 76 #define COPYDATA(x, a, b, c, d) \ 77 (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \ 78 : cuio_copydata((struct uio *)a,b,c,d) 79 80 static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); 81 static int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, 82 struct swcr_data *sw, caddr_t buf, int outtype); 83 static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); 84 static int swcr_process(void *, struct cryptop *, int); 85 static int swcr_newsession(void *, u_int32_t *, struct cryptoini *); 86 static int swcr_freesession(void *, u_int64_t); 87 88 /* 89 * Apply a symmetric encryption/decryption algorithm. 90 */ 91 static int 92 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, 93 int outtype) 94 { 95 unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; 96 unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; 97 struct enc_xform *exf; 98 int i, k, j, blks; 99 int count, ind; 100 101 exf = sw->sw_exf; 102 blks = exf->blocksize; 103 104 /* Check for non-padded data */ 105 if (crd->crd_len % blks) 106 return EINVAL; 107 108 /* Initialize the IV */ 109 if (crd->crd_flags & CRD_F_ENCRYPT) { 110 /* IV explicitly provided ? */ 111 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 112 bcopy(crd->crd_iv, iv, blks); 113 else { 114 /* Get random IV */ 115 for (i = 0; 116 i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN; 117 i += sizeof (u_int32_t)) { 118 u_int32_t temp = arc4random(); 119 120 bcopy(&temp, iv + i, sizeof(u_int32_t)); 121 } 122 /* 123 * What if the block size is not a multiple 124 * of sizeof (u_int32_t), which is the size of 125 * what arc4random() returns ? 126 */ 127 if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) { 128 u_int32_t temp = arc4random(); 129 130 bcopy (&temp, iv + i, 131 EALG_MAX_BLOCK_LEN - i); 132 } 133 } 134 135 /* Do we need to write the IV */ 136 if (!(crd->crd_flags & CRD_F_IV_PRESENT)) { 137 COPYBACK(outtype, buf, crd->crd_inject, blks, iv); 138 } 139 140 } else { /* Decryption */ 141 /* IV explicitly provided ? */ 142 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 143 bcopy(crd->crd_iv, iv, blks); 144 else { 145 /* Get IV off buf */ 146 COPYDATA(outtype, buf, crd->crd_inject, blks, iv); 147 } 148 } 149 150 ivp = iv; 151 152 if (outtype == CRYPTO_BUF_CONTIG) { 153 if (crd->crd_flags & CRD_F_ENCRYPT) { 154 for (i = crd->crd_skip; 155 i < crd->crd_skip + crd->crd_len; i += blks) { 156 /* XOR with the IV/previous block, as appropriate. */ 157 if (i == crd->crd_skip) 158 for (k = 0; k < blks; k++) 159 buf[i + k] ^= ivp[k]; 160 else 161 for (k = 0; k < blks; k++) 162 buf[i + k] ^= buf[i + k - blks]; 163 exf->encrypt(sw->sw_kschedule, buf + i); 164 } 165 } else { /* Decrypt */ 166 /* 167 * Start at the end, so we don't need to keep the encrypted 168 * block as the IV for the next block. 169 */ 170 for (i = crd->crd_skip + crd->crd_len - blks; 171 i >= crd->crd_skip; i -= blks) { 172 exf->decrypt(sw->sw_kschedule, buf + i); 173 174 /* XOR with the IV/previous block, as appropriate */ 175 if (i == crd->crd_skip) 176 for (k = 0; k < blks; k++) 177 buf[i + k] ^= ivp[k]; 178 else 179 for (k = 0; k < blks; k++) 180 buf[i + k] ^= buf[i + k - blks]; 181 } 182 } 183 184 return 0; 185 } else if (outtype == CRYPTO_BUF_MBUF) { 186 struct mbuf *m = (struct mbuf *) buf; 187 188 /* Find beginning of data */ 189 m = m_getptr(m, crd->crd_skip, &k); 190 if (m == NULL) 191 return EINVAL; 192 193 i = crd->crd_len; 194 195 while (i > 0) { 196 /* 197 * If there's insufficient data at the end of 198 * an mbuf, we have to do some copying. 199 */ 200 if (m->m_len < k + blks && m->m_len != k) { 201 m_copydata(m, k, blks, blk); 202 203 /* Actual encryption/decryption */ 204 if (crd->crd_flags & CRD_F_ENCRYPT) { 205 /* XOR with previous block */ 206 for (j = 0; j < blks; j++) 207 blk[j] ^= ivp[j]; 208 209 exf->encrypt(sw->sw_kschedule, blk); 210 211 /* 212 * Keep encrypted block for XOR'ing 213 * with next block 214 */ 215 bcopy(blk, iv, blks); 216 ivp = iv; 217 } else { /* decrypt */ 218 /* 219 * Keep encrypted block for XOR'ing 220 * with next block 221 */ 222 if (ivp == iv) 223 bcopy(blk, piv, blks); 224 else 225 bcopy(blk, iv, blks); 226 227 exf->decrypt(sw->sw_kschedule, blk); 228 229 /* XOR with previous block */ 230 for (j = 0; j < blks; j++) 231 blk[j] ^= ivp[j]; 232 233 if (ivp == iv) 234 bcopy(piv, iv, blks); 235 else 236 ivp = iv; 237 } 238 239 /* Copy back decrypted block */ 240 m_copyback(m, k, blks, blk); 241 242 /* Advance pointer */ 243 m = m_getptr(m, k + blks, &k); 244 if (m == NULL) 245 return EINVAL; 246 247 i -= blks; 248 249 /* Could be done... */ 250 if (i == 0) 251 break; 252 } 253 254 /* Skip possibly empty mbufs */ 255 if (k == m->m_len) { 256 for (m = m->m_next; m && m->m_len == 0; 257 m = m->m_next) 258 ; 259 k = 0; 260 } 261 262 /* Sanity check */ 263 if (m == NULL) 264 return EINVAL; 265 266 /* 267 * Warning: idat may point to garbage here, but 268 * we only use it in the while() loop, only if 269 * there are indeed enough data. 270 */ 271 idat = mtod(m, unsigned char *) + k; 272 273 while (m->m_len >= k + blks && i > 0) { 274 if (crd->crd_flags & CRD_F_ENCRYPT) { 275 /* XOR with previous block/IV */ 276 for (j = 0; j < blks; j++) 277 idat[j] ^= ivp[j]; 278 279 exf->encrypt(sw->sw_kschedule, idat); 280 ivp = idat; 281 } else { /* decrypt */ 282 /* 283 * Keep encrypted block to be used 284 * in next block's processing. 285 */ 286 if (ivp == iv) 287 bcopy(idat, piv, blks); 288 else 289 bcopy(idat, iv, blks); 290 291 exf->decrypt(sw->sw_kschedule, idat); 292 293 /* XOR with previous block/IV */ 294 for (j = 0; j < blks; j++) 295 idat[j] ^= ivp[j]; 296 297 if (ivp == iv) 298 bcopy(piv, iv, blks); 299 else 300 ivp = iv; 301 } 302 303 idat += blks; 304 k += blks; 305 i -= blks; 306 } 307 } 308 309 return 0; /* Done with mbuf encryption/decryption */ 310 } else if (outtype == CRYPTO_BUF_IOV) { 311 struct uio *uio = (struct uio *) buf; 312 313 #ifdef __FreeBSD__ 314 struct iovec *iov; 315 /* Find beginning of data */ 316 iov = cuio_getptr(uio, crd->crd_skip, &k); 317 if (iov == NULL) 318 return EINVAL; 319 320 i = crd->crd_len; 321 322 while (i > 0) { 323 /* 324 * If there's insufficient data at the end of 325 * an iovec, we have to do some copying. 326 */ 327 if (iov->iov_len < k + blks && iov->iov_len != k) { 328 cuio_copydata(uio, k, blks, blk); 329 330 /* Actual encryption/decryption */ 331 if (crd->crd_flags & CRD_F_ENCRYPT) { 332 /* XOR with previous block */ 333 for (j = 0; j < blks; j++) 334 blk[j] ^= ivp[j]; 335 336 exf->encrypt(sw->sw_kschedule, blk); 337 338 /* 339 * Keep encrypted block for XOR'ing 340 * with next block 341 */ 342 bcopy(blk, iv, blks); 343 ivp = iv; 344 } else { /* decrypt */ 345 /* 346 * Keep encrypted block for XOR'ing 347 * with next block 348 */ 349 if (ivp == iv) 350 bcopy(blk, piv, blks); 351 else 352 bcopy(blk, iv, blks); 353 354 exf->decrypt(sw->sw_kschedule, blk); 355 356 /* XOR with previous block */ 357 for (j = 0; j < blks; j++) 358 blk[j] ^= ivp[j]; 359 360 if (ivp == iv) 361 bcopy(piv, iv, blks); 362 else 363 ivp = iv; 364 } 365 366 /* Copy back decrypted block */ 367 cuio_copyback(uio, k, blks, blk); 368 369 /* Advance pointer */ 370 iov = cuio_getptr(uio, k + blks, &k); 371 if (iov == NULL) 372 return EINVAL; 373 374 i -= blks; 375 376 /* Could be done... */ 377 if (i == 0) 378 break; 379 } 380 381 /* 382 * Warning: idat may point to garbage here, but 383 * we only use it in the while() loop, only if 384 * there are indeed enough data. 385 */ 386 idat = (char *)iov->iov_base + k; 387 388 while (iov->iov_len >= k + blks && i > 0) { 389 if (crd->crd_flags & CRD_F_ENCRYPT) { 390 /* XOR with previous block/IV */ 391 for (j = 0; j < blks; j++) 392 idat[j] ^= ivp[j]; 393 394 exf->encrypt(sw->sw_kschedule, idat); 395 ivp = idat; 396 } else { /* decrypt */ 397 /* 398 * Keep encrypted block to be used 399 * in next block's processing. 400 */ 401 if (ivp == iv) 402 bcopy(idat, piv, blks); 403 else 404 bcopy(idat, iv, blks); 405 406 exf->decrypt(sw->sw_kschedule, idat); 407 408 /* XOR with previous block/IV */ 409 for (j = 0; j < blks; j++) 410 idat[j] ^= ivp[j]; 411 412 if (ivp == iv) 413 bcopy(piv, iv, blks); 414 else 415 ivp = iv; 416 } 417 418 idat += blks; 419 k += blks; 420 i -= blks; 421 } 422 } 423 424 return 0; /* Done with mbuf encryption/decryption */ 425 #else /* !freebsd iov */ 426 /* Find beginning of data */ 427 count = crd->crd_skip; 428 ind = cuio_getptr(uio, count, &k); 429 if (ind == -1) 430 return EINVAL; 431 432 i = crd->crd_len; 433 434 while (i > 0) { 435 /* 436 * If there's insufficient data at the end, 437 * we have to do some copying. 438 */ 439 if (uio->uio_iov[ind].iov_len < k + blks && 440 uio->uio_iov[ind].iov_len != k) { 441 cuio_copydata(uio, k, blks, blk); 442 443 /* Actual encryption/decryption */ 444 if (crd->crd_flags & CRD_F_ENCRYPT) { 445 /* XOR with previous block */ 446 for (j = 0; j < blks; j++) 447 blk[j] ^= ivp[j]; 448 449 exf->encrypt(sw->sw_kschedule, blk); 450 451 /* 452 * Keep encrypted block for XOR'ing 453 * with next block 454 */ 455 bcopy(blk, iv, blks); 456 ivp = iv; 457 } else { /* decrypt */ 458 /* 459 * Keep encrypted block for XOR'ing 460 * with next block 461 */ 462 if (ivp == iv) 463 bcopy(blk, piv, blks); 464 else 465 bcopy(blk, iv, blks); 466 467 exf->decrypt(sw->sw_kschedule, blk); 468 469 /* XOR with previous block */ 470 for (j = 0; j < blks; j++) 471 blk[j] ^= ivp[j]; 472 473 if (ivp == iv) 474 bcopy(piv, iv, blks); 475 else 476 ivp = iv; 477 } 478 479 /* Copy back decrypted block */ 480 cuio_copyback(uio, k, blks, blk); 481 482 count += blks; 483 484 /* Advance pointer */ 485 ind = cuio_getptr(uio, count, &k); 486 if (ind == -1) 487 return (EINVAL); 488 489 i -= blks; 490 491 /* Could be done... */ 492 if (i == 0) 493 break; 494 } 495 496 /* 497 * Warning: idat may point to garbage here, but 498 * we only use it in the while() loop, only if 499 * there are indeed enough data. 500 */ 501 idat = ((caddr_t)uio->uio_iov[ind].iov_base) + k; 502 503 while (uio->uio_iov[ind].iov_len >= k + blks && 504 i > 0) { 505 if (crd->crd_flags & CRD_F_ENCRYPT) { 506 /* XOR with previous block/IV */ 507 for (j = 0; j < blks; j++) 508 idat[j] ^= ivp[j]; 509 510 exf->encrypt(sw->sw_kschedule, idat); 511 ivp = idat; 512 } else { /* decrypt */ 513 /* 514 * Keep encrypted block to be used 515 * in next block's processing. 516 */ 517 if (ivp == iv) 518 bcopy(idat, piv, blks); 519 else 520 bcopy(idat, iv, blks); 521 522 exf->decrypt(sw->sw_kschedule, idat); 523 524 /* XOR with previous block/IV */ 525 for (j = 0; j < blks; j++) 526 idat[j] ^= ivp[j]; 527 528 if (ivp == iv) 529 bcopy(piv, iv, blks); 530 else 531 ivp = iv; 532 } 533 534 idat += blks; 535 count += blks; 536 k += blks; 537 i -= blks; 538 } 539 } 540 #endif 541 return 0; /* Done with mbuf encryption/decryption */ 542 } 543 544 /* Unreachable */ 545 return EINVAL; 546 } 547 548 /* 549 * Compute keyed-hash authenticator. 550 */ 551 static int 552 swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, 553 struct swcr_data *sw, caddr_t buf, int outtype) 554 { 555 unsigned char aalg[AALG_MAX_RESULT_LEN]; 556 struct auth_hash *axf; 557 union authctx ctx; 558 int err; 559 560 if (sw->sw_ictx == 0) 561 return EINVAL; 562 563 axf = sw->sw_axf; 564 565 bcopy(sw->sw_ictx, &ctx, axf->ctxsize); 566 567 switch (outtype) { 568 case CRYPTO_BUF_CONTIG: 569 axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len); 570 break; 571 case CRYPTO_BUF_MBUF: 572 err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len, 573 (int (*)(void*, caddr_t, unsigned int)) axf->Update, 574 (caddr_t) &ctx); 575 if (err) 576 return err; 577 break; 578 case CRYPTO_BUF_IOV: 579 #ifdef __FreeBSD__ 580 /*XXX FIXME: handle iov case*/ 581 return EINVAL; 582 #else 583 err = cuio_apply((struct uio *) buf, crd->crd_skip, 584 crd->crd_len, 585 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update, 586 (caddr_t) &ctx); 587 if (err) { 588 return err; 589 } 590 #endif 591 break; 592 default: 593 return EINVAL; 594 } 595 596 switch (sw->sw_alg) { 597 case CRYPTO_MD5_HMAC: 598 case CRYPTO_SHA1_HMAC: 599 case CRYPTO_SHA2_HMAC: 600 case CRYPTO_RIPEMD160_HMAC: 601 if (sw->sw_octx == NULL) 602 return EINVAL; 603 604 axf->Final(aalg, &ctx); 605 bcopy(sw->sw_octx, &ctx, axf->ctxsize); 606 axf->Update(&ctx, aalg, axf->hashsize); 607 axf->Final(aalg, &ctx); 608 break; 609 610 case CRYPTO_MD5_KPDK: 611 case CRYPTO_SHA1_KPDK: 612 if (sw->sw_octx == NULL) 613 return EINVAL; 614 615 axf->Update(&ctx, sw->sw_octx, sw->sw_klen); 616 axf->Final(aalg, &ctx); 617 break; 618 619 case CRYPTO_NULL_HMAC: 620 case CRYPTO_MD5: 621 case CRYPTO_SHA1: 622 axf->Final(aalg, &ctx); 623 break; 624 } 625 626 /* Inject the authentication data */ 627 switch (outtype) { 628 case CRYPTO_BUF_CONTIG: 629 bcopy(aalg, buf + crd->crd_inject, axf->authsize); 630 break; 631 case CRYPTO_BUF_MBUF: 632 m_copyback((struct mbuf *) buf, crd->crd_inject, 633 axf->authsize, aalg); 634 break; 635 case CRYPTO_BUF_IOV: 636 bcopy(aalg, crp->crp_mac, axf->authsize); 637 break; 638 default: 639 return EINVAL; 640 } 641 return 0; 642 } 643 644 /* 645 * Apply a compression/decompression algorithm 646 */ 647 static int 648 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, 649 caddr_t buf, int outtype) 650 { 651 u_int8_t *data, *out; 652 struct comp_algo *cxf; 653 int adj; 654 u_int32_t result; 655 656 cxf = sw->sw_cxf; 657 658 /* We must handle the whole buffer of data in one time 659 * then if there is not all the data in the mbuf, we must 660 * copy in a buffer. 661 */ 662 663 MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); 664 if (data == NULL) 665 return (EINVAL); 666 COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data); 667 668 if (crd->crd_flags & CRD_F_COMP) 669 result = cxf->compress(data, crd->crd_len, &out); 670 else 671 result = cxf->decompress(data, crd->crd_len, &out); 672 673 FREE(data, M_CRYPTO_DATA); 674 if (result == 0) 675 return EINVAL; 676 677 /* Copy back the (de)compressed data. m_copyback is 678 * extending the mbuf as necessary. 679 */ 680 sw->sw_size = result; 681 /* Check the compressed size when doing compression */ 682 if (crd->crd_flags & CRD_F_COMP) { 683 if (result > crd->crd_len) { 684 /* Compression was useless, we lost time */ 685 FREE(out, M_CRYPTO_DATA); 686 return 0; 687 } 688 } 689 690 COPYBACK(outtype, buf, crd->crd_skip, result, out); 691 if (result < crd->crd_len) { 692 adj = result - crd->crd_len; 693 if (outtype == CRYPTO_BUF_MBUF) { 694 adj = result - crd->crd_len; 695 m_adj((struct mbuf *)buf, adj); 696 } else { 697 struct uio *uio = (struct uio *)buf; 698 int ind; 699 700 adj = crd->crd_len - result; 701 ind = uio->uio_iovcnt - 1; 702 703 while (adj > 0 && ind >= 0) { 704 if (adj < uio->uio_iov[ind].iov_len) { 705 uio->uio_iov[ind].iov_len -= adj; 706 break; 707 } 708 709 adj -= uio->uio_iov[ind].iov_len; 710 uio->uio_iov[ind].iov_len = 0; 711 ind--; 712 uio->uio_iovcnt--; 713 } 714 } 715 } 716 FREE(out, M_CRYPTO_DATA); 717 return 0; 718 } 719 720 /* 721 * Generate a new software session. 722 */ 723 static int 724 swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) 725 { 726 struct swcr_data **swd; 727 struct auth_hash *axf; 728 struct enc_xform *txf; 729 struct comp_algo *cxf; 730 u_int32_t i; 731 int k, error; 732 733 if (sid == NULL || cri == NULL) 734 return EINVAL; 735 736 if (swcr_sessions) { 737 for (i = 1; i < swcr_sesnum; i++) 738 if (swcr_sessions[i] == NULL) 739 break; 740 } else 741 i = 1; /* NB: to silence compiler warning */ 742 743 if (swcr_sessions == NULL || i == swcr_sesnum) { 744 if (swcr_sessions == NULL) { 745 i = 1; /* We leave swcr_sessions[0] empty */ 746 swcr_sesnum = CRYPTO_SW_SESSIONS; 747 } else 748 swcr_sesnum *= 2; 749 750 swd = malloc(swcr_sesnum * sizeof(struct swcr_data *), 751 M_CRYPTO_DATA, M_NOWAIT); 752 if (swd == NULL) { 753 /* Reset session number */ 754 if (swcr_sesnum == CRYPTO_SW_SESSIONS) 755 swcr_sesnum = 0; 756 else 757 swcr_sesnum /= 2; 758 return ENOBUFS; 759 } 760 761 bzero(swd, swcr_sesnum * sizeof(struct swcr_data *)); 762 763 /* Copy existing sessions */ 764 if (swcr_sessions) { 765 bcopy(swcr_sessions, swd, 766 (swcr_sesnum / 2) * sizeof(struct swcr_data *)); 767 free(swcr_sessions, M_CRYPTO_DATA); 768 } 769 770 swcr_sessions = swd; 771 } 772 773 swd = &swcr_sessions[i]; 774 *sid = i; 775 776 while (cri) { 777 MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data), 778 M_CRYPTO_DATA, M_NOWAIT); 779 if (*swd == NULL) { 780 swcr_freesession(NULL, i); 781 return ENOBUFS; 782 } 783 bzero(*swd, sizeof(struct swcr_data)); 784 785 switch (cri->cri_alg) { 786 case CRYPTO_DES_CBC: 787 txf = &enc_xform_des; 788 goto enccommon; 789 case CRYPTO_3DES_CBC: 790 txf = &enc_xform_3des; 791 goto enccommon; 792 case CRYPTO_BLF_CBC: 793 txf = &enc_xform_blf; 794 goto enccommon; 795 case CRYPTO_CAST_CBC: 796 txf = &enc_xform_cast5; 797 goto enccommon; 798 case CRYPTO_SKIPJACK_CBC: 799 txf = &enc_xform_skipjack; 800 goto enccommon; 801 case CRYPTO_RIJNDAEL128_CBC: 802 txf = &enc_xform_rijndael128; 803 goto enccommon; 804 case CRYPTO_NULL_CBC: 805 txf = &enc_xform_null; 806 goto enccommon; 807 enccommon: 808 error = txf->setkey(&((*swd)->sw_kschedule), 809 cri->cri_key, cri->cri_klen / 8); 810 if (error) { 811 swcr_freesession(NULL, i); 812 return error; 813 } 814 (*swd)->sw_exf = txf; 815 break; 816 817 case CRYPTO_MD5_HMAC: 818 axf = &auth_hash_hmac_md5_96; 819 goto authcommon; 820 case CRYPTO_SHA1_HMAC: 821 axf = &auth_hash_hmac_sha1_96; 822 goto authcommon; 823 case CRYPTO_SHA2_HMAC: 824 if (cri->cri_klen == 256) 825 axf = &auth_hash_hmac_sha2_256; 826 else if (cri->cri_klen == 384) 827 axf = &auth_hash_hmac_sha2_384; 828 else if (cri->cri_klen == 512) 829 axf = &auth_hash_hmac_sha2_512; 830 else { 831 swcr_freesession(NULL, i); 832 return EINVAL; 833 } 834 goto authcommon; 835 case CRYPTO_NULL_HMAC: 836 axf = &auth_hash_null; 837 goto authcommon; 838 case CRYPTO_RIPEMD160_HMAC: 839 axf = &auth_hash_hmac_ripemd_160_96; 840 authcommon: 841 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 842 M_NOWAIT); 843 if ((*swd)->sw_ictx == NULL) { 844 swcr_freesession(NULL, i); 845 return ENOBUFS; 846 } 847 848 (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, 849 M_NOWAIT); 850 if ((*swd)->sw_octx == NULL) { 851 swcr_freesession(NULL, i); 852 return ENOBUFS; 853 } 854 855 for (k = 0; k < cri->cri_klen / 8; k++) 856 cri->cri_key[k] ^= HMAC_IPAD_VAL; 857 858 axf->Init((*swd)->sw_ictx); 859 axf->Update((*swd)->sw_ictx, cri->cri_key, 860 cri->cri_klen / 8); 861 axf->Update((*swd)->sw_ictx, hmac_ipad_buffer, 862 HMAC_BLOCK_LEN - (cri->cri_klen / 8)); 863 864 for (k = 0; k < cri->cri_klen / 8; k++) 865 cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); 866 867 axf->Init((*swd)->sw_octx); 868 axf->Update((*swd)->sw_octx, cri->cri_key, 869 cri->cri_klen / 8); 870 axf->Update((*swd)->sw_octx, hmac_opad_buffer, 871 HMAC_BLOCK_LEN - (cri->cri_klen / 8)); 872 873 for (k = 0; k < cri->cri_klen / 8; k++) 874 cri->cri_key[k] ^= HMAC_OPAD_VAL; 875 (*swd)->sw_axf = axf; 876 break; 877 878 case CRYPTO_MD5_KPDK: 879 axf = &auth_hash_key_md5; 880 goto auth2common; 881 882 case CRYPTO_SHA1_KPDK: 883 axf = &auth_hash_key_sha1; 884 auth2common: 885 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 886 M_NOWAIT); 887 if ((*swd)->sw_ictx == NULL) { 888 swcr_freesession(NULL, i); 889 return ENOBUFS; 890 } 891 892 /* Store the key so we can "append" it to the payload */ 893 (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA, 894 M_NOWAIT); 895 if ((*swd)->sw_octx == NULL) { 896 swcr_freesession(NULL, i); 897 return ENOBUFS; 898 } 899 900 (*swd)->sw_klen = cri->cri_klen / 8; 901 bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8); 902 axf->Init((*swd)->sw_ictx); 903 axf->Update((*swd)->sw_ictx, cri->cri_key, 904 cri->cri_klen / 8); 905 axf->Final(NULL, (*swd)->sw_ictx); 906 (*swd)->sw_axf = axf; 907 break; 908 909 case CRYPTO_MD5: 910 axf = &auth_hash_md5; 911 goto auth3common; 912 913 case CRYPTO_SHA1: 914 axf = &auth_hash_sha1; 915 auth3common: 916 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 917 M_NOWAIT); 918 if ((*swd)->sw_ictx == NULL) { 919 swcr_freesession(NULL, i); 920 return ENOBUFS; 921 } 922 923 axf->Init((*swd)->sw_ictx); 924 (*swd)->sw_axf = axf; 925 break; 926 927 case CRYPTO_DEFLATE_COMP: 928 cxf = &comp_algo_deflate; 929 (*swd)->sw_cxf = cxf; 930 break; 931 default: 932 swcr_freesession(NULL, i); 933 return EINVAL; 934 } 935 936 (*swd)->sw_alg = cri->cri_alg; 937 cri = cri->cri_next; 938 swd = &((*swd)->sw_next); 939 } 940 return 0; 941 } 942 943 /* 944 * Free a session. 945 */ 946 static int 947 swcr_freesession(void *arg, u_int64_t tid) 948 { 949 struct swcr_data *swd; 950 struct enc_xform *txf; 951 struct auth_hash *axf; 952 struct comp_algo *cxf; 953 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; 954 955 if (sid > swcr_sesnum || swcr_sessions == NULL || 956 swcr_sessions[sid] == NULL) 957 return EINVAL; 958 959 /* Silently accept and return */ 960 if (sid == 0) 961 return 0; 962 963 while ((swd = swcr_sessions[sid]) != NULL) { 964 swcr_sessions[sid] = swd->sw_next; 965 966 switch (swd->sw_alg) { 967 case CRYPTO_DES_CBC: 968 case CRYPTO_3DES_CBC: 969 case CRYPTO_BLF_CBC: 970 case CRYPTO_CAST_CBC: 971 case CRYPTO_SKIPJACK_CBC: 972 case CRYPTO_RIJNDAEL128_CBC: 973 case CRYPTO_NULL_CBC: 974 txf = swd->sw_exf; 975 976 if (swd->sw_kschedule) 977 txf->zerokey(&(swd->sw_kschedule)); 978 break; 979 980 case CRYPTO_MD5_HMAC: 981 case CRYPTO_SHA1_HMAC: 982 case CRYPTO_SHA2_HMAC: 983 case CRYPTO_RIPEMD160_HMAC: 984 case CRYPTO_NULL_HMAC: 985 axf = swd->sw_axf; 986 987 if (swd->sw_ictx) { 988 bzero(swd->sw_ictx, axf->ctxsize); 989 free(swd->sw_ictx, M_CRYPTO_DATA); 990 } 991 if (swd->sw_octx) { 992 bzero(swd->sw_octx, axf->ctxsize); 993 free(swd->sw_octx, M_CRYPTO_DATA); 994 } 995 break; 996 997 case CRYPTO_MD5_KPDK: 998 case CRYPTO_SHA1_KPDK: 999 axf = swd->sw_axf; 1000 1001 if (swd->sw_ictx) { 1002 bzero(swd->sw_ictx, axf->ctxsize); 1003 free(swd->sw_ictx, M_CRYPTO_DATA); 1004 } 1005 if (swd->sw_octx) { 1006 bzero(swd->sw_octx, swd->sw_klen); 1007 free(swd->sw_octx, M_CRYPTO_DATA); 1008 } 1009 break; 1010 1011 case CRYPTO_MD5: 1012 case CRYPTO_SHA1: 1013 axf = swd->sw_axf; 1014 1015 if (swd->sw_ictx) 1016 free(swd->sw_ictx, M_CRYPTO_DATA); 1017 break; 1018 1019 case CRYPTO_DEFLATE_COMP: 1020 cxf = swd->sw_cxf; 1021 break; 1022 } 1023 1024 FREE(swd, M_CRYPTO_DATA); 1025 } 1026 return 0; 1027 } 1028 1029 /* 1030 * Process a software request. 1031 */ 1032 static int 1033 swcr_process(void *arg, struct cryptop *crp, int hint) 1034 { 1035 struct cryptodesc *crd; 1036 struct swcr_data *sw; 1037 u_int32_t lid; 1038 int type; 1039 1040 /* Sanity check */ 1041 if (crp == NULL) 1042 return EINVAL; 1043 1044 if (crp->crp_desc == NULL || crp->crp_buf == NULL) { 1045 crp->crp_etype = EINVAL; 1046 goto done; 1047 } 1048 1049 lid = crp->crp_sid & 0xffffffff; 1050 if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { 1051 crp->crp_etype = ENOENT; 1052 goto done; 1053 } 1054 1055 if (crp->crp_flags & CRYPTO_F_IMBUF) { 1056 type = CRYPTO_BUF_MBUF; 1057 } else if (crp->crp_flags & CRYPTO_F_IOV) { 1058 type = CRYPTO_BUF_IOV; 1059 } else { 1060 type = CRYPTO_BUF_CONTIG; 1061 } 1062 1063 /* Go through crypto descriptors, processing as we go */ 1064 for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 1065 /* 1066 * Find the crypto context. 1067 * 1068 * XXX Note that the logic here prevents us from having 1069 * XXX the same algorithm multiple times in a session 1070 * XXX (or rather, we can but it won't give us the right 1071 * XXX results). To do that, we'd need some way of differentiating 1072 * XXX between the various instances of an algorithm (so we can 1073 * XXX locate the correct crypto context). 1074 */ 1075 for (sw = swcr_sessions[lid]; 1076 sw && sw->sw_alg != crd->crd_alg; 1077 sw = sw->sw_next) 1078 ; 1079 1080 /* No such context ? */ 1081 if (sw == NULL) { 1082 crp->crp_etype = EINVAL; 1083 goto done; 1084 } 1085 1086 switch (sw->sw_alg) { 1087 case CRYPTO_DES_CBC: 1088 case CRYPTO_3DES_CBC: 1089 case CRYPTO_BLF_CBC: 1090 case CRYPTO_CAST_CBC: 1091 case CRYPTO_SKIPJACK_CBC: 1092 case CRYPTO_RIJNDAEL128_CBC: 1093 if ((crp->crp_etype = swcr_encdec(crd, sw, 1094 crp->crp_buf, type)) != 0) 1095 goto done; 1096 break; 1097 case CRYPTO_NULL_CBC: 1098 crp->crp_etype = 0; 1099 break; 1100 case CRYPTO_MD5_HMAC: 1101 case CRYPTO_SHA1_HMAC: 1102 case CRYPTO_SHA2_HMAC: 1103 case CRYPTO_RIPEMD160_HMAC: 1104 case CRYPTO_NULL_HMAC: 1105 case CRYPTO_MD5_KPDK: 1106 case CRYPTO_SHA1_KPDK: 1107 case CRYPTO_MD5: 1108 case CRYPTO_SHA1: 1109 if ((crp->crp_etype = swcr_authcompute(crp, crd, sw, 1110 crp->crp_buf, type)) != 0) 1111 goto done; 1112 break; 1113 1114 case CRYPTO_DEFLATE_COMP: 1115 if ((crp->crp_etype = swcr_compdec(crd, sw, 1116 crp->crp_buf, type)) != 0) 1117 goto done; 1118 else 1119 crp->crp_olen = (int)sw->sw_size; 1120 break; 1121 1122 default: 1123 /* Unknown/unsupported algorithm */ 1124 crp->crp_etype = EINVAL; 1125 goto done; 1126 } 1127 } 1128 1129 done: 1130 crypto_done(crp); 1131 return 0; 1132 } 1133 1134 /* 1135 * Initialize the driver, called from the kernel main(). 1136 */ 1137 /*static*/ 1138 void 1139 swcr_init(void) 1140 { 1141 swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE); 1142 if (swcr_id < 0) { 1143 /* This should never happen */ 1144 panic("Software crypto device cannot initialize!"); 1145 } 1146 1147 crypto_register(swcr_id, CRYPTO_DES_CBC, 1148 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL); 1149 #define REGISTER(alg) \ 1150 crypto_register(swcr_id, alg, 0, 0, NULL, NULL, NULL, NULL) 1151 1152 REGISTER(CRYPTO_3DES_CBC); 1153 REGISTER(CRYPTO_BLF_CBC); 1154 REGISTER(CRYPTO_CAST_CBC); 1155 REGISTER(CRYPTO_SKIPJACK_CBC); 1156 REGISTER(CRYPTO_NULL_CBC); 1157 REGISTER(CRYPTO_MD5_HMAC); 1158 REGISTER(CRYPTO_SHA1_HMAC); 1159 REGISTER(CRYPTO_SHA2_HMAC); 1160 REGISTER(CRYPTO_RIPEMD160_HMAC); 1161 REGISTER(CRYPTO_NULL_HMAC); 1162 REGISTER(CRYPTO_MD5_KPDK); 1163 REGISTER(CRYPTO_SHA1_KPDK); 1164 REGISTER(CRYPTO_MD5); 1165 REGISTER(CRYPTO_SHA1); 1166 REGISTER(CRYPTO_RIJNDAEL128_CBC); 1167 REGISTER(CRYPTO_DEFLATE_COMP); 1168 #undef REGISTER 1169 } 1170 1171 #ifdef __FreeBSD__ 1172 SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL) 1173 #endif 1174