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