1 /* $OpenBSD: cryptosoft.c,v 1.29 2001/11/09 03:11:38 deraadt Exp $ */ 2 3 /* 4 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) 5 * 6 * This code was written by Angelos D. Keromytis in Athens, Greece, in 7 * February 2000. Network Security Technologies Inc. (NSTI) kindly 8 * supported the development of this code. 9 * 10 * Copyright (c) 2000, 2001 Angelos D. Keromytis 11 * 12 * Permission to use, copy, and modify this software with or without fee 13 * is hereby granted, provided that this entire notice is included in 14 * all source code copies of any software which is or includes a copy or 15 * modification of this software. 16 * 17 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 18 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 19 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 20 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 21 * PURPOSE. 22 */ 23 24 #include <sys/param.h> 25 #include <sys/systm.h> 26 #include <sys/malloc.h> 27 #include <sys/mbuf.h> 28 #include <sys/sysctl.h> 29 #include <sys/errno.h> 30 #include <sys/md5k.h> 31 #include <dev/rndvar.h> 32 #include <crypto/sha1.h> 33 #include <crypto/rmd160.h> 34 #include <crypto/cast.h> 35 #include <crypto/skipjack.h> 36 #include <crypto/blf.h> 37 #include <crypto/cryptodev.h> 38 #include <crypto/cryptosoft.h> 39 #include <crypto/xform.h> 40 41 u_int8_t hmac_ipad_buffer[64] = { 42 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 43 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 44 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 45 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 46 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 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 }; 51 52 u_int8_t hmac_opad_buffer[64] = { 53 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 54 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 55 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 56 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 57 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 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 }; 62 63 64 struct swcr_data **swcr_sessions = NULL; 65 u_int32_t swcr_sesnum = 0; 66 int32_t swcr_id = -1; 67 68 /* 69 * Apply a symmetric encryption/decryption algorithm. 70 */ 71 int 72 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, 73 int outtype) 74 { 75 unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; 76 unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; 77 struct enc_xform *exf; 78 int i, k, j, blks; 79 struct mbuf *m; 80 81 exf = sw->sw_exf; 82 blks = exf->blocksize; 83 84 /* Check for non-padded data */ 85 if (crd->crd_len % blks) 86 return EINVAL; 87 88 if (outtype == CRYPTO_BUF_CONTIG) { 89 if (crd->crd_flags & CRD_F_ENCRYPT) { 90 /* IV explicitly provided ? */ 91 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 92 bcopy(crd->crd_iv, sw->sw_iv, blks); 93 94 if (!(crd->crd_flags & CRD_F_IV_PRESENT)) 95 bcopy(sw->sw_iv, buf + crd->crd_inject, blks); 96 97 for (i = crd->crd_skip; 98 i < crd->crd_skip + crd->crd_len; i += blks) { 99 /* XOR with the IV/previous block, as appropriate. */ 100 if (i == crd->crd_skip) 101 for (k = 0; k < blks; k++) 102 buf[i + k] ^= sw->sw_iv[k]; 103 else 104 for (k = 0; k < blks; k++) 105 buf[i + k] ^= buf[i + k - blks]; 106 exf->encrypt(sw->sw_kschedule, buf + i); 107 } 108 109 /* Keep the last block */ 110 bcopy(buf + crd->crd_len - blks, sw->sw_iv, blks); 111 112 } else { /* Decrypt */ 113 /* IV explicitly provided ? */ 114 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 115 bcopy(crd->crd_iv, sw->sw_iv, blks); 116 else /* IV preceeds data */ 117 bcopy(buf + crd->crd_inject, sw->sw_iv, blks); 118 119 /* 120 * Start at the end, so we don't need to keep the encrypted 121 * block as the IV for the next block. 122 */ 123 for (i = crd->crd_skip + crd->crd_len - blks; 124 i >= crd->crd_skip; i -= blks) { 125 exf->decrypt(sw->sw_kschedule, buf + i); 126 127 /* XOR with the IV/previous block, as appropriate */ 128 if (i == crd->crd_skip) 129 for (k = 0; k < blks; k++) 130 buf[i + k] ^= sw->sw_iv[k]; 131 else 132 for (k = 0; k < blks; k++) 133 buf[i + k] ^= buf[i + k - blks]; 134 } 135 } 136 return 0; 137 } else { 138 m = (struct mbuf *) buf; 139 140 /* Initialize the IV */ 141 if (crd->crd_flags & CRD_F_ENCRYPT) { 142 /* IV explicitly provided ? */ 143 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 144 bcopy(crd->crd_iv, iv, blks); 145 else { 146 /* Use IV from context */ 147 bcopy(sw->sw_iv, iv, blks); 148 } 149 150 /* Do we need to write the IV */ 151 if (!(crd->crd_flags & CRD_F_IV_PRESENT)) 152 m_copyback(m, crd->crd_inject, blks, iv); 153 154 } else { /* Decryption */ 155 /* IV explicitly provided ? */ 156 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 157 bcopy(crd->crd_iv, iv, blks); 158 else { 159 /* Get IV off mbuf */ 160 m_copydata(m, crd->crd_inject, blks, iv); 161 } 162 } 163 164 ivp = iv; 165 166 /* Find beginning of data */ 167 m = m_getptr(m, crd->crd_skip, &k); 168 if (m == NULL) 169 return EINVAL; 170 171 i = crd->crd_len; 172 173 while (i > 0) { 174 /* 175 * If there's insufficient data at the end of 176 * an mbuf, we have to do some copying. 177 */ 178 if (m->m_len < k + blks && m->m_len != k) { 179 m_copydata(m, k, blks, blk); 180 181 /* Actual encryption/decryption */ 182 if (crd->crd_flags & CRD_F_ENCRYPT) { 183 /* XOR with previous block */ 184 for (j = 0; j < blks; j++) 185 blk[j] ^= ivp[j]; 186 187 exf->encrypt(sw->sw_kschedule, blk); 188 189 /* 190 * Keep encrypted block for XOR'ing 191 * with next block 192 */ 193 bcopy(blk, iv, blks); 194 ivp = iv; 195 } else { /* decrypt */ 196 /* 197 * Keep encrypted block for XOR'ing 198 * with next block 199 */ 200 if (ivp == iv) 201 bcopy(blk, piv, blks); 202 else 203 bcopy(blk, iv, blks); 204 205 exf->decrypt(sw->sw_kschedule, blk); 206 207 /* XOR with previous block */ 208 for (j = 0; j < blks; j++) 209 blk[j] ^= ivp[j]; 210 211 if (ivp == iv) 212 bcopy(piv, iv, blks); 213 else 214 ivp = iv; 215 } 216 217 /* Copy back decrypted block */ 218 m_copyback(m, k, blks, blk); 219 220 /* Advance pointer */ 221 m = m_getptr(m, k + blks, &k); 222 if (m == NULL) 223 return EINVAL; 224 225 i -= blks; 226 227 /* Could be done... */ 228 if (i == 0) 229 break; 230 } 231 232 /* Skip possibly empty mbufs */ 233 if (k == m->m_len) { 234 for (m = m->m_next; m && m->m_len == 0; 235 m = m->m_next) 236 ; 237 k = 0; 238 } 239 240 /* Sanity check */ 241 if (m == NULL) 242 return EINVAL; 243 244 /* 245 * Warning: idat may point to garbage here, but 246 * we only use it in the while() loop, only if 247 * there are indeed enough data. 248 */ 249 idat = mtod(m, unsigned char *) + k; 250 251 while (m->m_len >= k + blks && i > 0) { 252 if (crd->crd_flags & CRD_F_ENCRYPT) { 253 /* XOR with previous block/IV */ 254 for (j = 0; j < blks; j++) 255 idat[j] ^= ivp[j]; 256 257 exf->encrypt(sw->sw_kschedule, idat); 258 ivp = idat; 259 } else { /* decrypt */ 260 /* 261 * Keep encrypted block to be used 262 * in next block's processing. 263 */ 264 if (ivp == iv) 265 bcopy(idat, piv, blks); 266 else 267 bcopy(idat, iv, blks); 268 269 exf->decrypt(sw->sw_kschedule, idat); 270 271 /* XOR with previous block/IV */ 272 for (j = 0; j < blks; j++) 273 idat[j] ^= ivp[j]; 274 275 if (ivp == iv) 276 bcopy(piv, iv, blks); 277 else 278 ivp = iv; 279 } 280 281 idat += blks; 282 k += blks; 283 i -= blks; 284 } 285 } 286 287 /* Keep the last block */ 288 if (crd->crd_flags & CRD_F_ENCRYPT) 289 bcopy(ivp, sw->sw_iv, blks); 290 291 return 0; /* Done with mbuf encryption/decryption */ 292 } 293 294 /* Unreachable */ 295 return EINVAL; 296 } 297 298 /* 299 * Compute keyed-hash authenticator. 300 */ 301 int 302 swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, 303 caddr_t buf, int outtype) 304 { 305 unsigned char aalg[AALG_MAX_RESULT_LEN]; 306 struct auth_hash *axf; 307 union authctx ctx; 308 int err; 309 310 if (sw->sw_ictx == 0) 311 return EINVAL; 312 313 axf = sw->sw_axf; 314 315 bcopy(sw->sw_ictx, &ctx, axf->ctxsize); 316 317 if (outtype == CRYPTO_BUF_CONTIG) 318 axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len); 319 else { 320 err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len, 321 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update, 322 (caddr_t) &ctx); 323 if (err) 324 return err; 325 } 326 327 switch (sw->sw_alg) { 328 case CRYPTO_MD5_HMAC: 329 case CRYPTO_SHA1_HMAC: 330 case CRYPTO_RIPEMD160_HMAC: 331 if (sw->sw_octx == NULL) 332 return EINVAL; 333 334 axf->Final(aalg, &ctx); 335 bcopy(sw->sw_octx, &ctx, axf->ctxsize); 336 axf->Update(&ctx, aalg, axf->hashsize); 337 axf->Final(aalg, &ctx); 338 break; 339 340 case CRYPTO_MD5_KPDK: 341 case CRYPTO_SHA1_KPDK: 342 if (sw->sw_octx == NULL) 343 return EINVAL; 344 345 axf->Update(&ctx, sw->sw_octx, sw->sw_klen); 346 axf->Final(aalg, &ctx); 347 break; 348 } 349 350 /* Inject the authentication data */ 351 if (outtype == CRYPTO_BUF_CONTIG) 352 bcopy(aalg, buf + crd->crd_inject, axf->authsize); 353 else 354 m_copyback((struct mbuf *) buf, crd->crd_inject, 355 axf->authsize, aalg); 356 return 0; 357 } 358 359 /* 360 * Apply a compression/decompression algorithm 361 */ 362 int 363 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, 364 caddr_t buf, int outtype) 365 { 366 u_int8_t *data, *out; 367 struct comp_algo *cxf; 368 int k, adj; 369 u_int32_t result; 370 struct mbuf *m, *m1; 371 372 cxf = sw->sw_cxf; 373 374 if (outtype == CRYPTO_BUF_CONTIG) { 375 if (crd->crd_flags & CRD_F_COMP) 376 result = cxf->compress(buf + crd->crd_skip, 377 crd->crd_len, &out); 378 else 379 result = cxf->decompress(buf + crd->crd_skip, 380 crd->crd_len, &out); 381 } else { /* mbuf */ 382 m = (struct mbuf *)buf; 383 384 /* Find beginning of data */ 385 m1 = m_getptr(m, crd->crd_skip, &k); 386 if (m1 == NULL) 387 return EINVAL; 388 /* We must handle the whole buffer of data in one time 389 * then if there is not all the data in the mbuf, we must 390 * copy in a buffer. 391 */ 392 393 MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, 394 M_NOWAIT); 395 if (data == NULL) 396 return EINVAL; 397 m_copydata(m1, k, crd->crd_len, data); 398 399 if (crd->crd_flags & CRD_F_COMP) 400 result = cxf->compress(data, crd->crd_len, &out); 401 else 402 result = cxf->decompress(data, crd->crd_len, &out); 403 } 404 405 if (outtype == CRYPTO_BUF_CONTIG) { 406 if (result == 0) 407 return EINVAL; 408 sw->sw_size = result; 409 /* Check the compressed size when doing compression */ 410 if (crd->crd_flags & CRD_F_COMP) { 411 if (result > crd->crd_len) { 412 /* Compression was useless, we lost time */ 413 FREE(out, M_CRYPTO_DATA); 414 return 0; 415 } 416 } 417 buf = out; 418 /* Don't forget to FREE buf later */ 419 return 0; 420 } else { 421 FREE(data, M_CRYPTO_DATA); 422 if (result == 0) 423 return EINVAL; 424 /* Copy back the (de)compressed data. m_copyback is 425 * extending the mbuf as necessary. 426 */ 427 sw->sw_size = result; 428 /* Check the compressed size when doing compression */ 429 if (crd->crd_flags & CRD_F_COMP) { 430 if (result > crd->crd_len) { 431 /* Compression was useless, we lost time */ 432 FREE(out, M_CRYPTO_DATA); 433 return 0; 434 } 435 } 436 m_copyback(m1, k, result, out); 437 if (result < crd->crd_len) { 438 adj = result - crd->crd_len; 439 m_adj(m, adj); 440 } 441 FREE(out, M_CRYPTO_DATA); 442 return 0; 443 } 444 445 /* Unreachable */ 446 return EINVAL; 447 } 448 449 /* 450 * Generate a new software session. 451 */ 452 int 453 swcr_newsession(u_int32_t *sid, struct cryptoini *cri) 454 { 455 struct swcr_data **swd; 456 struct auth_hash *axf; 457 struct enc_xform *txf; 458 struct comp_algo *cxf; 459 u_int32_t i; 460 int k; 461 462 if (sid == NULL || cri == NULL) 463 return EINVAL; 464 465 if (swcr_sessions) { 466 for (i = 1; i < swcr_sesnum; i++) 467 if (swcr_sessions[i] == NULL) 468 break; 469 } 470 471 if (swcr_sessions == NULL || i == swcr_sesnum) { 472 if (swcr_sessions == NULL) { 473 i = 1; /* We leave swcr_sessions[0] empty */ 474 swcr_sesnum = CRYPTO_SW_SESSIONS; 475 } else 476 swcr_sesnum *= 2; 477 478 swd = malloc(swcr_sesnum * sizeof(struct swcr_data *), 479 M_CRYPTO_DATA, M_NOWAIT); 480 if (swd == NULL) { 481 /* Reset session number */ 482 if (swcr_sesnum == CRYPTO_SW_SESSIONS) 483 swcr_sesnum = 0; 484 else 485 swcr_sesnum /= 2; 486 return ENOBUFS; 487 } 488 489 bzero(swd, swcr_sesnum * sizeof(struct swcr_data *)); 490 491 /* Copy existing sessions */ 492 if (swcr_sessions) { 493 bcopy(swcr_sessions, swd, 494 (swcr_sesnum / 2) * sizeof(struct swcr_data *)); 495 free(swcr_sessions, M_CRYPTO_DATA); 496 } 497 498 swcr_sessions = swd; 499 } 500 501 swd = &swcr_sessions[i]; 502 *sid = i; 503 504 while (cri) { 505 MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data), 506 M_CRYPTO_DATA, M_NOWAIT); 507 if (*swd == NULL) { 508 swcr_freesession(i); 509 return ENOBUFS; 510 } 511 bzero(*swd, sizeof(struct swcr_data)); 512 513 switch (cri->cri_alg) { 514 case CRYPTO_DES_CBC: 515 txf = &enc_xform_des; 516 goto enccommon; 517 case CRYPTO_3DES_CBC: 518 txf = &enc_xform_3des; 519 goto enccommon; 520 case CRYPTO_BLF_CBC: 521 txf = &enc_xform_blf; 522 goto enccommon; 523 case CRYPTO_CAST_CBC: 524 txf = &enc_xform_cast5; 525 goto enccommon; 526 case CRYPTO_SKIPJACK_CBC: 527 txf = &enc_xform_skipjack; 528 goto enccommon; 529 case CRYPTO_RIJNDAEL128_CBC: 530 txf = &enc_xform_rijndael128; 531 goto enccommon; 532 enccommon: 533 txf->setkey(&((*swd)->sw_kschedule), cri->cri_key, 534 cri->cri_klen / 8); 535 (*swd)->sw_iv = malloc(txf->blocksize, M_CRYPTO_DATA, M_NOWAIT); 536 if ((*swd)->sw_iv == NULL) { 537 swcr_freesession(i); 538 return ENOBUFS; 539 } 540 (*swd)->sw_exf = txf; 541 get_random_bytes((*swd)->sw_iv, txf->blocksize); 542 break; 543 544 case CRYPTO_MD5_HMAC: 545 axf = &auth_hash_hmac_md5_96; 546 goto authcommon; 547 case CRYPTO_SHA1_HMAC: 548 axf = &auth_hash_hmac_sha1_96; 549 goto authcommon; 550 case CRYPTO_RIPEMD160_HMAC: 551 axf = &auth_hash_hmac_ripemd_160_96; 552 authcommon: 553 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 554 M_NOWAIT); 555 if ((*swd)->sw_ictx == NULL) { 556 swcr_freesession(i); 557 return ENOBUFS; 558 } 559 560 (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, 561 M_NOWAIT); 562 if ((*swd)->sw_octx == NULL) { 563 swcr_freesession(i); 564 return ENOBUFS; 565 } 566 567 for (k = 0; k < cri->cri_klen / 8; k++) 568 cri->cri_key[k] ^= HMAC_IPAD_VAL; 569 570 axf->Init((*swd)->sw_ictx); 571 axf->Update((*swd)->sw_ictx, cri->cri_key, 572 cri->cri_klen / 8); 573 axf->Update((*swd)->sw_ictx, hmac_ipad_buffer, 574 HMAC_BLOCK_LEN - (cri->cri_klen / 8)); 575 576 for (k = 0; k < cri->cri_klen / 8; k++) 577 cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); 578 579 axf->Init((*swd)->sw_octx); 580 axf->Update((*swd)->sw_octx, cri->cri_key, 581 cri->cri_klen / 8); 582 axf->Update((*swd)->sw_octx, hmac_opad_buffer, 583 HMAC_BLOCK_LEN - (cri->cri_klen / 8)); 584 585 for (k = 0; k < cri->cri_klen / 8; k++) 586 cri->cri_key[k] ^= HMAC_OPAD_VAL; 587 (*swd)->sw_axf = axf; 588 break; 589 590 case CRYPTO_MD5_KPDK: 591 axf = &auth_hash_key_md5; 592 goto auth2common; 593 594 case CRYPTO_SHA1_KPDK: 595 axf = &auth_hash_key_sha1; 596 auth2common: 597 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, 598 M_NOWAIT); 599 if ((*swd)->sw_ictx == NULL) { 600 swcr_freesession(i); 601 return ENOBUFS; 602 } 603 604 /* Store the key so we can "append" it to the payload */ 605 (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA, 606 M_NOWAIT); 607 if ((*swd)->sw_octx == NULL) { 608 swcr_freesession(i); 609 return ENOBUFS; 610 } 611 612 (*swd)->sw_klen = cri->cri_klen / 8; 613 bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8); 614 axf->Init((*swd)->sw_ictx); 615 axf->Update((*swd)->sw_ictx, cri->cri_key, 616 cri->cri_klen / 8); 617 axf->Final(NULL, (*swd)->sw_ictx); 618 (*swd)->sw_axf = axf; 619 break; 620 621 case CRYPTO_DEFLATE_COMP: 622 cxf = &comp_algo_deflate; 623 (*swd)->sw_cxf = cxf; 624 break; 625 default: 626 swcr_freesession(i); 627 return EINVAL; 628 } 629 630 (*swd)->sw_alg = cri->cri_alg; 631 cri = cri->cri_next; 632 swd = &((*swd)->sw_next); 633 } 634 return 0; 635 } 636 637 /* 638 * Free a session. 639 */ 640 int 641 swcr_freesession(u_int64_t tid) 642 { 643 struct swcr_data *swd; 644 struct enc_xform *txf; 645 struct auth_hash *axf; 646 struct comp_algo *cxf; 647 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; 648 649 if (sid > swcr_sesnum || swcr_sessions == NULL || 650 swcr_sessions[sid] == NULL) 651 return EINVAL; 652 653 /* Silently accept and return */ 654 if (sid == 0) 655 return 0; 656 657 while ((swd = swcr_sessions[sid]) != NULL) { 658 swcr_sessions[sid] = swd->sw_next; 659 660 switch (swd->sw_alg) { 661 case CRYPTO_DES_CBC: 662 case CRYPTO_3DES_CBC: 663 case CRYPTO_BLF_CBC: 664 case CRYPTO_CAST_CBC: 665 case CRYPTO_SKIPJACK_CBC: 666 case CRYPTO_RIJNDAEL128_CBC: 667 txf = swd->sw_exf; 668 669 if (swd->sw_kschedule) 670 txf->zerokey(&(swd->sw_kschedule)); 671 if (swd->sw_iv) 672 free(swd->sw_iv, M_CRYPTO_DATA); 673 break; 674 675 case CRYPTO_MD5_HMAC: 676 case CRYPTO_SHA1_HMAC: 677 case CRYPTO_RIPEMD160_HMAC: 678 axf = swd->sw_axf; 679 680 if (swd->sw_ictx) { 681 bzero(swd->sw_ictx, axf->ctxsize); 682 free(swd->sw_ictx, M_CRYPTO_DATA); 683 } 684 if (swd->sw_octx) { 685 bzero(swd->sw_octx, axf->ctxsize); 686 free(swd->sw_octx, M_CRYPTO_DATA); 687 } 688 break; 689 690 case CRYPTO_MD5_KPDK: 691 case CRYPTO_SHA1_KPDK: 692 axf = swd->sw_axf; 693 694 if (swd->sw_ictx) { 695 bzero(swd->sw_ictx, axf->ctxsize); 696 free(swd->sw_ictx, M_CRYPTO_DATA); 697 } 698 if (swd->sw_octx) { 699 bzero(swd->sw_octx, swd->sw_klen); 700 free(swd->sw_octx, M_CRYPTO_DATA); 701 } 702 break; 703 704 case CRYPTO_DEFLATE_COMP: 705 cxf = swd->sw_cxf; 706 break; 707 } 708 709 FREE(swd, M_CRYPTO_DATA); 710 } 711 return 0; 712 } 713 714 /* 715 * Process a software request. 716 */ 717 int 718 swcr_process(struct cryptop *crp) 719 { 720 struct cryptodesc *crd; 721 struct swcr_data *sw; 722 u_int32_t lid; 723 int type; 724 725 /* Sanity check */ 726 if (crp == NULL) 727 return EINVAL; 728 729 if (crp->crp_desc == NULL || crp->crp_buf == NULL) { 730 crp->crp_etype = EINVAL; 731 goto done; 732 } 733 734 lid = crp->crp_sid & 0xffffffff; 735 if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { 736 crp->crp_etype = ENOENT; 737 goto done; 738 } 739 740 if (crp->crp_flags & CRYPTO_F_IMBUF) 741 type = CRYPTO_BUF_MBUF; 742 else 743 type = CRYPTO_BUF_CONTIG; 744 745 /* Go through crypto descriptors, processing as we go */ 746 for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 747 /* 748 * Find the crypto context. 749 * 750 * XXX Note that the logic here prevents us from having 751 * XXX the same algorithm multiple times in a session 752 * XXX (or rather, we can but it won't give us the right 753 * XXX results). To do that, we'd need some way of differentiating 754 * XXX between the various instances of an algorithm (so we can 755 * XXX locate the correct crypto context). 756 */ 757 for (sw = swcr_sessions[lid]; 758 sw && sw->sw_alg != crd->crd_alg; 759 sw = sw->sw_next) 760 ; 761 762 /* No such context ? */ 763 if (sw == NULL) { 764 crp->crp_etype = EINVAL; 765 goto done; 766 } 767 768 switch (sw->sw_alg) { 769 case CRYPTO_DES_CBC: 770 case CRYPTO_3DES_CBC: 771 case CRYPTO_BLF_CBC: 772 case CRYPTO_CAST_CBC: 773 case CRYPTO_SKIPJACK_CBC: 774 case CRYPTO_RIJNDAEL128_CBC: 775 if ((crp->crp_etype = swcr_encdec(crd, sw, 776 crp->crp_buf, type)) != 0) 777 goto done; 778 break; 779 case CRYPTO_MD5_HMAC: 780 case CRYPTO_SHA1_HMAC: 781 case CRYPTO_RIPEMD160_HMAC: 782 case CRYPTO_MD5_KPDK: 783 case CRYPTO_SHA1_KPDK: 784 if ((crp->crp_etype = swcr_authcompute(crd, sw, 785 crp->crp_buf, type)) != 0) 786 goto done; 787 break; 788 789 case CRYPTO_DEFLATE_COMP: 790 if ((crp->crp_etype = swcr_compdec(crd, sw, 791 crp->crp_buf, type)) != 0) 792 goto done; 793 else 794 crp->crp_olen = (int)sw->sw_size; 795 break; 796 797 default: 798 /* Unknown/unsupported algorithm */ 799 crp->crp_etype = EINVAL; 800 goto done; 801 } 802 } 803 804 done: 805 crypto_done(crp); 806 return 0; 807 } 808 809 /* 810 * Initialize the driver, called from the kernel main(). 811 */ 812 void 813 swcr_init(void) 814 { 815 swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE); 816 if (swcr_id >= 0) { 817 crypto_register(swcr_id, CRYPTO_DES_CBC, 0, 0, swcr_newsession, 818 swcr_freesession, swcr_process); 819 crypto_register(swcr_id, CRYPTO_3DES_CBC, 0, 0, 820 NULL, NULL, NULL); 821 crypto_register(swcr_id, CRYPTO_BLF_CBC, 0, 0, 822 NULL, NULL, NULL); 823 crypto_register(swcr_id, CRYPTO_CAST_CBC, 0, 0, 824 NULL, NULL, NULL); 825 crypto_register(swcr_id, CRYPTO_SKIPJACK_CBC, 0, 0, 826 NULL, NULL, NULL); 827 crypto_register(swcr_id, CRYPTO_MD5_HMAC, 0, 0, 828 NULL, NULL, NULL); 829 crypto_register(swcr_id, CRYPTO_SHA1_HMAC, 0, 0, 830 NULL, NULL, NULL); 831 crypto_register(swcr_id, CRYPTO_RIPEMD160_HMAC, 0, 0, 832 NULL, NULL, NULL); 833 crypto_register(swcr_id, CRYPTO_MD5_KPDK, 0, 0, 834 NULL, NULL, NULL); 835 crypto_register(swcr_id, CRYPTO_SHA1_KPDK, 0, 0, 836 NULL, NULL, NULL); 837 crypto_register(swcr_id, CRYPTO_RIJNDAEL128_CBC, 0, 0, 838 NULL, NULL, NULL); 839 crypto_register(swcr_id, CRYPTO_DEFLATE_COMP, 0, 0, 840 NULL, NULL, NULL); 841 return; 842 } 843 844 /* This should never happen */ 845 panic("Software crypto device cannot initialize!"); 846 } 847