rmisec.c revision 198627
1/*- 2 * Copyright (c) 2003-2009 RMI Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of RMI Corporation, nor the names of its contributors, 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * RMI_BSD */ 30 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/proc.h> 35#include <sys/errno.h> 36#include <sys/malloc.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/mbuf.h> 40#include <sys/lock.h> 41#include <sys/mutex.h> 42#include <sys/sysctl.h> 43 44#include <vm/vm.h> 45#include <vm/pmap.h> 46 47#include <machine/bus.h> 48#include <machine/resource.h> 49#include <sys/bus.h> 50#include <sys/rman.h> 51 52#include <opencrypto/cryptodev.h> 53#include <sys/random.h> 54 55#include <dev/rmi/sec/rmilib.h> 56 57/*#define RMI_SEC_DEBUG */ 58 59 60void xlr_sec_print_data(struct cryptop *crp); 61 62static int xlr_sec_newsession(void *arg, uint32_t * sidp, struct cryptoini *cri); 63static int xlr_sec_freesession(void *arg, uint64_t tid); 64static int xlr_sec_process(void *arg, struct cryptop *crp, int hint); 65 66 67static int xlr_sec_probe(device_t); 68static int xlr_sec_attach(device_t); 69static int xlr_sec_detach(device_t); 70 71 72static device_method_t xlr_sec_methods[] = { 73 /* device interface */ 74 DEVMETHOD(device_probe, xlr_sec_probe), 75 DEVMETHOD(device_attach, xlr_sec_attach), 76 DEVMETHOD(device_detach, xlr_sec_detach), 77 78 /* bus interface */ 79 DEVMETHOD(bus_print_child, bus_generic_print_child), 80 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 81 82 {0, 0} 83}; 84 85static driver_t xlr_sec_driver = { 86 "rmisec", 87 xlr_sec_methods, 88 sizeof(struct xlr_sec_softc) 89}; 90static devclass_t xlr_sec_devclass; 91 92DRIVER_MODULE(rmisec, iodi, xlr_sec_driver, xlr_sec_devclass, 0, 0); 93MODULE_DEPEND(rmisec, crypto, 1, 1, 1); 94 95 96 97static int 98xlr_sec_probe(device_t dev) 99{ 100 return (BUS_PROBE_DEFAULT); 101 102} 103 104 105/* 106 * Attach an interface that successfully probed. 107 */ 108static int 109xlr_sec_attach(device_t dev) 110{ 111 112 struct xlr_sec_softc *sc = device_get_softc(dev); 113 114 bzero(sc, sizeof(*sc)); 115 sc->sc_dev = dev; 116 117 118 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "rmi crypto driver", MTX_DEF); 119 120 sc->sc_cid = crypto_get_driverid(0); 121 if (sc->sc_cid < 0) { 122 printf("xlr_sec - error : could not get the driver id\n"); 123 goto error_exit; 124 } 125 if (crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, 126 xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) 127 printf("register failed for CRYPTO_DES_CBC\n"); 128 129 if (crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, 130 xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) 131 printf("register failed for CRYPTO_3DES_CBC\n"); 132 133 if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, 134 xlr_sec_newsession, xlr_sec_freesession, 135 xlr_sec_process, sc) != 0) 136 printf("register failed for CRYPTO_AES_CBC\n"); 137 138 if (crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0, 139 xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) 140 printf("register failed for CRYPTO_ARC4\n"); 141 142 143 if (crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0, 144 xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) 145 printf("register failed for CRYPTO_MD5\n"); 146 147 if (crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0, 148 xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) 149 printf("register failed for CRYPTO_SHA1\n"); 150 151 if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, 152 xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) 153 printf("register failed for CRYPTO_MD5_HMAC\n"); 154 155 if (crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, 156 xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) 157 printf("register failed for CRYPTO_SHA1_HMAC\n"); 158 159 160 xlr_sec_init(sc); 161 return (0); 162 163 164error_exit: 165 return (ENXIO); 166 167} 168 169 170/* 171 * Detach an interface that successfully probed. 172 */ 173static int 174xlr_sec_detach(device_t dev) 175{ 176 int sesn; 177 struct xlr_sec_softc *sc = device_get_softc(dev); 178 struct xlr_sec_session *ses = NULL; 179 symkey_desc_pt desc; 180 181 for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { 182 ses = &sc->sc_sessions[sesn]; 183 desc = (symkey_desc_pt) ses->desc_ptr; 184 free(desc->user.kern_src, M_DEVBUF); 185 free(desc->user.kern_dest, M_DEVBUF); 186 free(desc->next_src_buf, M_DEVBUF); 187 free(desc->next_dest_buf, M_DEVBUF); 188 free(ses->desc_ptr, M_DEVBUF); 189 } 190 191 return (0); 192} 193 194 195 196 197/* 198 * Allocate a new 'session' and return an encoded session id. 'sidp' 199 * contains our registration id, and should contain an encoded session 200 * id on successful allocation. 201 */ 202static int 203xlr_sec_newsession(void *arg, u_int32_t * sidp, struct cryptoini *cri) 204{ 205 struct cryptoini *c; 206 struct xlr_sec_softc *sc = arg; 207 int mac = 0, cry = 0, sesn; 208 struct xlr_sec_session *ses = NULL; 209 210 211 if (sidp == NULL || cri == NULL || sc == NULL) 212 return (EINVAL); 213 214 215 if (sc->sc_sessions == NULL) { 216 ses = sc->sc_sessions = (struct xlr_sec_session *)malloc( 217 sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); 218 if (ses == NULL) 219 return (ENOMEM); 220 221 ses->desc_ptr = (void *)xlr_sec_allocate_desc((void *)ses); 222 if (ses->desc_ptr == NULL) 223 return (ENOMEM); 224 225 sesn = 0; 226 ses->sessionid = sesn; 227 sc->sc_nsessions = 1; 228 } else { 229 for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { 230 if (!sc->sc_sessions[sesn].hs_used) { 231 ses = &sc->sc_sessions[sesn]; 232 break; 233 } 234 } 235 236 if (ses == NULL) { 237 sesn = sc->sc_nsessions; 238 ses = (struct xlr_sec_session *)malloc((sesn + 1) * 239 sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); 240 if (ses == NULL) 241 return (ENOMEM); 242 bcopy(sc->sc_sessions, ses, sesn * sizeof(struct xlr_sec_session)); 243 bzero(sc->sc_sessions, sesn * sizeof(struct xlr_sec_session)); 244 free(sc->sc_sessions, M_DEVBUF); 245 sc->sc_sessions = ses; 246 ses = &sc->sc_sessions[sesn]; 247 ses->sessionid = sesn; 248 ses->desc_ptr = (void *)xlr_sec_allocate_desc((void *)ses); 249 if (ses->desc_ptr == NULL) 250 return (ENOMEM); 251 sc->sc_nsessions++; 252 } 253 } 254 ses->hs_used = 1; 255 256 257 for (c = cri; c != NULL; c = c->cri_next) { 258 259 switch (c->cri_alg) { 260 case CRYPTO_MD5: 261 case CRYPTO_SHA1: 262 case CRYPTO_MD5_HMAC: 263 case CRYPTO_SHA1_HMAC: 264 if (mac) 265 return (EINVAL); 266 mac = 1; 267 ses->hs_mlen = c->cri_mlen; 268 if (ses->hs_mlen == 0) { 269 switch (c->cri_alg) { 270 case CRYPTO_MD5: 271 case CRYPTO_MD5_HMAC: 272 ses->hs_mlen = 16; 273 break; 274 case CRYPTO_SHA1: 275 case CRYPTO_SHA1_HMAC: 276 ses->hs_mlen = 20; 277 break; 278 } 279 } 280 break; 281 case CRYPTO_DES_CBC: 282 case CRYPTO_3DES_CBC: 283 case CRYPTO_AES_CBC: 284 /* XXX this may read fewer, does it matter? */ 285 /* 286 * read_random(ses->hs_iv, c->cri_alg == 287 * CRYPTO_AES_CBC ? XLR_SEC_AES_IV_LENGTH : 288 * XLR_SEC_IV_LENGTH); 289 */ 290 /* FALLTHROUGH */ 291 case CRYPTO_ARC4: 292 if (cry) 293 return (EINVAL); 294 cry = 1; 295 break; 296 default: 297 return (EINVAL); 298 } 299 } 300 if (mac == 0 && cry == 0) 301 return (EINVAL); 302 303 *sidp = XLR_SEC_SID(device_get_unit(sc->sc_dev), sesn); 304 return (0); 305} 306 307/* 308 * Deallocate a session. 309 * XXX this routine should run a zero'd mac/encrypt key into context ram. 310 * XXX to blow away any keys already stored there. 311 */ 312static int 313xlr_sec_freesession(void *arg, u_int64_t tid) 314{ 315 struct xlr_sec_softc *sc = arg; 316 int session; 317 u_int32_t sid = CRYPTO_SESID2LID(tid); 318 319 if (sc == NULL) 320 return (EINVAL); 321 322 session = XLR_SEC_SESSION(sid); 323 if (session >= sc->sc_nsessions) 324 return (EINVAL); 325 326 sc->sc_sessions[session].hs_used = 0; 327 328 return (0); 329} 330 331#ifdef RMI_SEC_DEBUG 332 333void 334xlr_sec_print_data(struct cryptop *crp) 335{ 336 int i, key_len; 337 struct cryptodesc *crp_desc; 338 339 printf("session id = 0x%llx, crp_ilen = %d, crp_olen=%d \n", 340 crp->crp_sid, crp->crp_ilen, crp->crp_olen); 341 342 printf("crp_flags = 0x%x\n", crp->crp_flags); 343 344 345 printf("crp buf:\n"); 346 for (i = 0; i < crp->crp_ilen; i++) { 347 printf("%c ", crp->crp_buf[i]); 348 if (i % 10 == 0) 349 printf("\n"); 350 } 351 352 printf("\n"); 353 printf("****************** desc ****************\n"); 354 crp_desc = crp->crp_desc; 355 printf("crd_skip=%d, crd_len=%d, crd_flags=0x%x, crd_alg=%d\n", 356 crp_desc->crd_skip, crp_desc->crd_len, crp_desc->crd_flags, crp_desc->crd_alg); 357 358 key_len = crp_desc->crd_klen / 8; 359 printf("key(%d) :\n", key_len); 360 for (i = 0; i < key_len; i++) 361 printf("%d", crp_desc->crd_key[i]); 362 printf("\n"); 363 364 printf(" IV : \n"); 365 for (i = 0; i < EALG_MAX_BLOCK_LEN; i++) 366 printf("%d", crp_desc->crd_iv[i]); 367 printf("\n"); 368 369 printf("crd_next=%p\n", crp_desc->crd_next); 370 return; 371} 372 373#endif 374 375 376static int 377xlr_sec_process(void *arg, struct cryptop *crp, int hint) 378{ 379 struct xlr_sec_softc *sc = arg; 380 struct xlr_sec_command *cmd = NULL; 381 int session, err; 382 struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; 383 struct xlr_sec_session *ses; 384 385 if (crp == NULL || crp->crp_callback == NULL) { 386 return (EINVAL); 387 } 388 session = XLR_SEC_SESSION(crp->crp_sid); 389 if (sc == NULL || session >= sc->sc_nsessions) { 390 err = EINVAL; 391 goto errout; 392 } 393 ses = &sc->sc_sessions[session]; 394 395 cmd = &ses->cmd; 396 if (cmd == NULL) { 397 err = ENOMEM; 398 goto errout; 399 } 400 crd1 = crp->crp_desc; 401 if (crd1 == NULL) { 402 err = EINVAL; 403 goto errout; 404 } 405 crd2 = crd1->crd_next; 406 407 if (crd2 == NULL) { 408 if (crd1->crd_alg == CRYPTO_MD5_HMAC || 409 crd1->crd_alg == CRYPTO_SHA1_HMAC || 410 crd1->crd_alg == CRYPTO_SHA1 || 411 crd1->crd_alg == CRYPTO_MD5) { 412 maccrd = crd1; 413 enccrd = NULL; 414 } else if (crd1->crd_alg == CRYPTO_DES_CBC || 415 crd1->crd_alg == CRYPTO_3DES_CBC || 416 crd1->crd_alg == CRYPTO_AES_CBC || 417 crd1->crd_alg == CRYPTO_ARC4) { 418 maccrd = NULL; 419 enccrd = crd1; 420 } else { 421 err = EINVAL; 422 goto errout; 423 } 424 } else { 425 if ((crd1->crd_alg == CRYPTO_MD5_HMAC || 426 crd1->crd_alg == CRYPTO_SHA1_HMAC || 427 crd1->crd_alg == CRYPTO_MD5 || 428 crd1->crd_alg == CRYPTO_SHA1) && 429 (crd2->crd_alg == CRYPTO_DES_CBC || 430 crd2->crd_alg == CRYPTO_3DES_CBC || 431 crd2->crd_alg == CRYPTO_AES_CBC || 432 crd2->crd_alg == CRYPTO_ARC4)) { 433 maccrd = crd1; 434 enccrd = crd2; 435 } else if ((crd1->crd_alg == CRYPTO_DES_CBC || 436 crd1->crd_alg == CRYPTO_ARC4 || 437 crd1->crd_alg == CRYPTO_3DES_CBC || 438 crd1->crd_alg == CRYPTO_AES_CBC) && 439 (crd2->crd_alg == CRYPTO_MD5_HMAC || 440 crd2->crd_alg == CRYPTO_SHA1_HMAC || 441 crd2->crd_alg == CRYPTO_MD5 || 442 crd2->crd_alg == CRYPTO_SHA1) && 443 (crd1->crd_flags & CRD_F_ENCRYPT)) { 444 enccrd = crd1; 445 maccrd = crd2; 446 } else { 447 err = EINVAL; 448 goto errout; 449 } 450 } 451 452 bzero(&cmd->op, sizeof(xlr_sec_io_t)); 453 454 cmd->op.source_buf = (uint64_t) (unsigned long)crp->crp_buf; 455 cmd->op.source_buf_size = crp->crp_ilen; 456 if (crp->crp_flags & CRYPTO_F_REL) { 457 cmd->op.dest_buf = (uint64_t) (unsigned long)crp->crp_buf; 458 cmd->op.dest_buf_size = crp->crp_ilen; 459 } else { 460 cmd->op.dest_buf = (uint64_t) (unsigned long)crp->crp_buf; 461 cmd->op.dest_buf_size = crp->crp_ilen; 462 } 463 cmd->op.num_packets = 1; 464 cmd->op.num_fragments = 1; 465 466 467 if (cmd->op.source_buf_size > SEC_MAX_FRAG_LEN) { 468 ses->multi_frag_flag = 1; 469 } else { 470 ses->multi_frag_flag = 0; 471 } 472 473 if (maccrd) { 474 cmd->maccrd = maccrd; 475 cmd->op.cipher_op = XLR_SEC_CIPHER_MODE_PASS; 476 cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_NONE; 477 cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_NONE; 478 cmd->op.cipher_init = 0; 479 cmd->op.cipher_offset = 0; 480 481 switch (maccrd->crd_alg) { 482 case CRYPTO_MD5: 483 cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_MD5; 484 cmd->op.digest_init = XLR_SEC_DIGEST_INIT_NEWKEY; 485 cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; 486 cmd->op.digest_offset = 0; 487 488 cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; 489 cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; 490 cmd->op.cksum_offset = 0; 491 492 cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; 493 cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; 494 cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; 495 cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; 496 cmd->op.pkt_iv = XLR_SEC_PKT_IV_OLD; 497 cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; 498 499 500 default: 501 printf("currently not handled\n"); 502 } 503 } 504 if (enccrd) { 505 cmd->enccrd = enccrd; 506 507#ifdef RMI_SEC_DEBUG 508 xlr_sec_print_data(crp); 509#endif 510 511 if (enccrd->crd_flags & CRD_F_ENCRYPT) { 512 cmd->op.cipher_op = XLR_SEC_CIPHER_OP_ENCRYPT; 513 } else 514 cmd->op.cipher_op = XLR_SEC_CIPHER_OP_DECRYPT; 515 516 switch (enccrd->crd_alg) { 517 case CRYPTO_DES_CBC: 518 case CRYPTO_3DES_CBC: 519 if (enccrd->crd_alg == CRYPTO_DES_CBC) { 520 cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_DES; 521 memcpy(&cmd->op.crypt_key[0], enccrd->crd_key, XLR_SEC_DES_KEY_LENGTH); 522 } else { 523 cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_3DES; 524 //if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) { 525 memcpy(&cmd->op.crypt_key[0], enccrd->crd_key, XLR_SEC_3DES_KEY_LENGTH); 526 } 527 } 528 529 cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; 530 cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; 531 cmd->op.cipher_offset = XLR_SEC_DES_IV_LENGTH; 532 533 cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; 534 cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; 535 cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; 536 cmd->op.digest_offset = 0; 537 538 cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; 539 cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; 540 cmd->op.cksum_offset = 0; 541 542 cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; 543 cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; 544 cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; 545 cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; 546 cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; 547 cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; 548 549 //if ((!(enccrd->crd_flags & CRD_F_IV_PRESENT)) && 550 if ((enccrd->crd_flags & CRD_F_IV_EXPLICIT)) { 551 memcpy(&cmd->op.initial_vector[0], enccrd->crd_iv, XLR_SEC_DES_IV_LENGTH); 552 } 553 break; 554 555 case CRYPTO_AES_CBC: 556 if (enccrd->crd_alg == CRYPTO_AES_CBC) { 557 cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_AES128; 558 //if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) { 559 memcpy(&cmd->op.crypt_key[0], enccrd->crd_key, XLR_SEC_AES128_KEY_LENGTH); 560 } 561 } 562 cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; 563 cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; 564 cmd->op.cipher_offset = XLR_SEC_AES_BLOCK_SIZE; 565 566 cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; 567 cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; 568 cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; 569 cmd->op.digest_offset = 0; 570 571 cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; 572 cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; 573 cmd->op.cksum_offset = 0; 574 575 cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; 576 cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; 577 cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; 578 cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; 579 cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; 580 cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; 581 582 //if (!(enccrd->crd_flags & CRD_F_IV_PRESENT)) { 583 if ((enccrd->crd_flags & CRD_F_IV_EXPLICIT)) { 584 memcpy(&cmd->op.initial_vector[0], enccrd->crd_iv, XLR_SEC_AES_BLOCK_SIZE); 585 } 586 // 587 } 588 break; 589 } 590 } 591 cmd->crp = crp; 592 cmd->session_num = session; 593 xlr_sec_setup(ses, cmd, (symkey_desc_pt) ses->desc_ptr); 594 595 return (0); 596 597errout: 598 if (cmd != NULL) 599 free(cmd, M_DEVBUF); 600 crp->crp_etype = err; 601 crypto_done(crp); 602 return (err); 603} 604