cryptodev.c (158831) | cryptodev.c (167755) |
---|---|
1/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */ 2 3/*- 4 * Copyright (c) 2001 Theo de Raadt | 1/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */ 2 3/*- 4 * Copyright (c) 2001 Theo de Raadt |
5 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting |
|
5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright --- 14 unchanged lines hidden (view full) --- 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Effort sponsored in part by the Defense Advanced Research Projects 30 * Agency (DARPA) and Air Force Research Laboratory, Air Force 31 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 32 */ 33 34#include <sys/cdefs.h> | 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright --- 14 unchanged lines hidden (view full) --- 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Effort sponsored in part by the Defense Advanced Research Projects 31 * Agency (DARPA) and Air Force Research Laboratory, Air Force 32 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 33 */ 34 35#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/opencrypto/cryptodev.c 158831 2006-05-22 16:24:11Z pjd $"); | 36__FBSDID("$FreeBSD: head/sys/opencrypto/cryptodev.c 167755 2007-03-21 03:42:51Z sam $"); |
36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/malloc.h> 40#include <sys/mbuf.h> 41#include <sys/lock.h> 42#include <sys/mutex.h> 43#include <sys/sysctl.h> 44#include <sys/file.h> 45#include <sys/filedesc.h> 46#include <sys/errno.h> 47#include <sys/uio.h> 48#include <sys/random.h> 49#include <sys/conf.h> 50#include <sys/kernel.h> 51#include <sys/module.h> 52#include <sys/fcntl.h> | 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/mbuf.h> 42#include <sys/lock.h> 43#include <sys/mutex.h> 44#include <sys/sysctl.h> 45#include <sys/file.h> 46#include <sys/filedesc.h> 47#include <sys/errno.h> 48#include <sys/uio.h> 49#include <sys/random.h> 50#include <sys/conf.h> 51#include <sys/kernel.h> 52#include <sys/module.h> 53#include <sys/fcntl.h> |
54#include <sys/bus.h> |
|
53 54#include <opencrypto/cryptodev.h> 55#include <opencrypto/xform.h> 56 57struct csession { 58 TAILQ_ENTRY(csession) next; 59 u_int64_t sid; 60 u_int32_t ses; --- 47 unchanged lines hidden (view full) --- 108static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, 109 u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *, 110 struct auth_hash *); 111static int csefree(struct csession *); 112 113static int cryptodev_op(struct csession *, struct crypt_op *, 114 struct ucred *, struct thread *td); 115static int cryptodev_key(struct crypt_kop *); | 55 56#include <opencrypto/cryptodev.h> 57#include <opencrypto/xform.h> 58 59struct csession { 60 TAILQ_ENTRY(csession) next; 61 u_int64_t sid; 62 u_int32_t ses; --- 47 unchanged lines hidden (view full) --- 110static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, 111 u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *, 112 struct auth_hash *); 113static int csefree(struct csession *); 114 115static int cryptodev_op(struct csession *, struct crypt_op *, 116 struct ucred *, struct thread *td); 117static int cryptodev_key(struct crypt_kop *); |
118static int cryptodev_find(struct crypt_find_op *); |
|
116 117static int 118cryptof_rw( 119 struct file *fp, 120 struct uio *uio, 121 struct ucred *active_cred, 122 int flags, 123 struct thread *td) 124{ 125 126 return (EIO); 127} 128 | 119 120static int 121cryptof_rw( 122 struct file *fp, 123 struct uio *uio, 124 struct ucred *active_cred, 125 int flags, 126 struct thread *td) 127{ 128 129 return (EIO); 130} 131 |
132/* 133 * Check a crypto identifier to see if it requested 134 * a software device/driver. This can be done either 135 * by device name/class or through search constraints. 136 */ 137static int 138checkforsoftware(int crid) 139{ 140 if (crid & CRYPTOCAP_F_SOFTWARE) 141 return EINVAL; /* XXX */ 142 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 && 143 (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0) 144 return EINVAL; /* XXX */ 145 return 0; 146} 147 |
|
129/* ARGSUSED */ 130static int 131cryptof_ioctl( 132 struct file *fp, 133 u_long cmd, 134 void *data, 135 struct ucred *active_cred, 136 struct thread *td) 137{ | 148/* ARGSUSED */ 149static int 150cryptof_ioctl( 151 struct file *fp, 152 u_long cmd, 153 void *data, 154 struct ucred *active_cred, 155 struct thread *td) 156{ |
157#define SES2(p) ((struct session2_op *)p) |
|
138 struct cryptoini cria, crie; 139 struct fcrypt *fcr = fp->f_data; 140 struct csession *cse; 141 struct session_op *sop; 142 struct crypt_op *cop; 143 struct enc_xform *txform = NULL; 144 struct auth_hash *thash = NULL; | 158 struct cryptoini cria, crie; 159 struct fcrypt *fcr = fp->f_data; 160 struct csession *cse; 161 struct session_op *sop; 162 struct crypt_op *cop; 163 struct enc_xform *txform = NULL; 164 struct auth_hash *thash = NULL; |
165 struct crypt_kop *kop; |
|
145 u_int64_t sid; 146 u_int32_t ses; | 166 u_int64_t sid; 167 u_int32_t ses; |
147 int error = 0; | 168 int error = 0, crid; |
148 | 169 |
149 /* 150 * XXX: Not sure Giant is needed, but better safe than sorry 151 */ 152 mtx_lock(&Giant); | |
153 switch (cmd) { 154 case CIOCGSESSION: | 170 switch (cmd) { 171 case CIOCGSESSION: |
172 case CIOCGSESSION2: |
|
155 sop = (struct session_op *)data; 156 switch (sop->cipher) { 157 case 0: 158 break; 159 case CRYPTO_DES_CBC: 160 txform = &enc_xform_des; 161 break; 162 case CRYPTO_3DES_CBC: --- 13 unchanged lines hidden (view full) --- 176 break; 177 case CRYPTO_NULL_CBC: 178 txform = &enc_xform_null; 179 break; 180 case CRYPTO_ARC4: 181 txform = &enc_xform_arc4; 182 break; 183 default: | 173 sop = (struct session_op *)data; 174 switch (sop->cipher) { 175 case 0: 176 break; 177 case CRYPTO_DES_CBC: 178 txform = &enc_xform_des; 179 break; 180 case CRYPTO_3DES_CBC: --- 13 unchanged lines hidden (view full) --- 194 break; 195 case CRYPTO_NULL_CBC: 196 txform = &enc_xform_null; 197 break; 198 case CRYPTO_ARC4: 199 txform = &enc_xform_arc4; 200 break; 201 default: |
184 mtx_unlock(&Giant); | |
185 return (EINVAL); 186 } 187 188 switch (sop->mac) { 189 case 0: 190 break; 191 case CRYPTO_MD5_HMAC: 192 thash = &auth_hash_hmac_md5; --- 20 unchanged lines hidden (view full) --- 213 case CRYPTO_SHA1: 214 thash = &auth_hash_sha1; 215 break; 216#endif 217 case CRYPTO_NULL_HMAC: 218 thash = &auth_hash_null; 219 break; 220 default: | 202 return (EINVAL); 203 } 204 205 switch (sop->mac) { 206 case 0: 207 break; 208 case CRYPTO_MD5_HMAC: 209 thash = &auth_hash_hmac_md5; --- 20 unchanged lines hidden (view full) --- 230 case CRYPTO_SHA1: 231 thash = &auth_hash_sha1; 232 break; 233#endif 234 case CRYPTO_NULL_HMAC: 235 thash = &auth_hash_null; 236 break; 237 default: |
221 mtx_unlock(&Giant); | |
222 return (EINVAL); 223 } 224 225 bzero(&crie, sizeof(crie)); 226 bzero(&cria, sizeof(cria)); 227 228 if (txform) { 229 crie.cri_alg = txform->type; --- 25 unchanged lines hidden (view full) --- 255 MALLOC(cria.cri_key, u_int8_t *, 256 cria.cri_klen / 8, M_XDATA, M_WAITOK); 257 if ((error = copyin(sop->mackey, cria.cri_key, 258 cria.cri_klen / 8))) 259 goto bail; 260 } 261 } 262 | 238 return (EINVAL); 239 } 240 241 bzero(&crie, sizeof(crie)); 242 bzero(&cria, sizeof(cria)); 243 244 if (txform) { 245 crie.cri_alg = txform->type; --- 25 unchanged lines hidden (view full) --- 271 MALLOC(cria.cri_key, u_int8_t *, 272 cria.cri_klen / 8, M_XDATA, M_WAITOK); 273 if ((error = copyin(sop->mackey, cria.cri_key, 274 cria.cri_klen / 8))) 275 goto bail; 276 } 277 } 278 |
263 error = crypto_newsession(&sid, (txform ? &crie : &cria), 1); 264 if (error) { 265 if (crypto_devallowsoft) { 266 error = crypto_newsession(&sid, 267 (txform ? &crie : &cria), 0); 268 } | 279 /* NB: CIOGSESSION2 has the crid */ 280 if (cmd == CIOCGSESSION2) { 281 crid = SES2(sop)->crid; 282 error = checkforsoftware(crid); |
269 if (error) 270 goto bail; | 283 if (error) 284 goto bail; |
271 } | 285 } else 286 crid = CRYPTOCAP_F_HARDWARE; 287 error = crypto_newsession(&sid, (txform ? &crie : &cria), crid); 288 if (error) 289 goto bail; |
272 273 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, 274 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform, 275 thash); 276 277 if (cse == NULL) { 278 crypto_freesession(sid); 279 error = EINVAL; 280 goto bail; 281 } 282 sop->ses = cse->ses; | 290 291 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, 292 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform, 293 thash); 294 295 if (cse == NULL) { 296 crypto_freesession(sid); 297 error = EINVAL; 298 goto bail; 299 } 300 sop->ses = cse->ses; |
283 | 301 if (cmd == CIOCGSESSION2) { 302 /* return hardware/driver id */ 303 SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid); 304 } |
284bail: 285 if (error) { 286 if (crie.cri_key) 287 FREE(crie.cri_key, M_XDATA); 288 if (cria.cri_key) 289 FREE(cria.cri_key, M_XDATA); 290 } 291 break; 292 case CIOCFSESSION: 293 ses = *(u_int32_t *)data; 294 cse = csefind(fcr, ses); | 305bail: 306 if (error) { 307 if (crie.cri_key) 308 FREE(crie.cri_key, M_XDATA); 309 if (cria.cri_key) 310 FREE(cria.cri_key, M_XDATA); 311 } 312 break; 313 case CIOCFSESSION: 314 ses = *(u_int32_t *)data; 315 cse = csefind(fcr, ses); |
295 if (cse == NULL) { 296 mtx_unlock(&Giant); | 316 if (cse == NULL) |
297 return (EINVAL); | 317 return (EINVAL); |
298 } | |
299 csedelete(fcr, cse); 300 error = csefree(cse); 301 break; 302 case CIOCCRYPT: 303 cop = (struct crypt_op *)data; 304 cse = csefind(fcr, cop->ses); | 318 csedelete(fcr, cse); 319 error = csefree(cse); 320 break; 321 case CIOCCRYPT: 322 cop = (struct crypt_op *)data; 323 cse = csefind(fcr, cop->ses); |
305 if (cse == NULL) { 306 mtx_unlock(&Giant); | 324 if (cse == NULL) |
307 return (EINVAL); | 325 return (EINVAL); |
308 } | |
309 error = cryptodev_op(cse, cop, active_cred, td); 310 break; 311 case CIOCKEY: | 326 error = cryptodev_op(cse, cop, active_cred, td); 327 break; 328 case CIOCKEY: |
312 error = cryptodev_key((struct crypt_kop *)data); | 329 case CIOCKEY2: 330 if (!crypto_userasymcrypto) 331 return (EPERM); /* XXX compat? */ 332 mtx_lock(&Giant); 333 kop = (struct crypt_kop *)data; 334 if (cmd == CIOCKEY) { 335 /* NB: crypto core enforces s/w driver use */ 336 kop->crk_crid = 337 CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE; 338 } 339 error = cryptodev_key(kop); 340 mtx_unlock(&Giant); |
313 break; 314 case CIOCASYMFEAT: | 341 break; 342 case CIOCASYMFEAT: |
315 error = crypto_getfeat((int *)data); | 343 if (!crypto_userasymcrypto) { 344 /* 345 * NB: if user asym crypto operations are 346 * not permitted return "no algorithms" 347 * so well-behaved applications will just 348 * fallback to doing them in software. 349 */ 350 *(int *)data = 0; 351 } else 352 error = crypto_getfeat((int *)data); |
316 break; | 353 break; |
354 case CIOCFINDDEV: 355 error = cryptodev_find((struct crypt_find_op *)data); 356 break; |
|
317 default: 318 error = EINVAL; | 357 default: 358 error = EINVAL; |
359 break; |
|
319 } | 360 } |
320 mtx_unlock(&Giant); | |
321 return (error); | 361 return (error); |
362#undef SES2 |
|
322} 323 324static int cryptodev_cb(void *); 325 326 327static int 328cryptodev_op( 329 struct csession *cse, --- 150 unchanged lines hidden (view full) --- 480 return (error); 481} 482 483static int 484cryptodev_cb(void *op) 485{ 486 struct cryptop *crp = (struct cryptop *) op; 487 struct csession *cse = (struct csession *)crp->crp_opaque; | 363} 364 365static int cryptodev_cb(void *); 366 367 368static int 369cryptodev_op( 370 struct csession *cse, --- 150 unchanged lines hidden (view full) --- 521 return (error); 522} 523 524static int 525cryptodev_cb(void *op) 526{ 527 struct cryptop *crp = (struct cryptop *) op; 528 struct csession *cse = (struct csession *)crp->crp_opaque; |
529 int error; |
|
488 | 530 |
489 cse->error = crp->crp_etype; 490 if (crp->crp_etype == EAGAIN) 491 return crypto_dispatch(crp); | 531 error = crp->crp_etype; 532 if (error == EAGAIN) 533 error = crypto_dispatch(crp); |
492 mtx_lock(&cse->lock); | 534 mtx_lock(&cse->lock); |
493 wakeup_one(crp); | 535 if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) { 536 cse->error = error; 537 wakeup_one(crp); 538 } |
494 mtx_unlock(&cse->lock); 495 return (0); 496} 497 498static int 499cryptodevkey_cb(void *op) 500{ 501 struct cryptkop *krp = (struct cryptkop *) op; 502 | 539 mtx_unlock(&cse->lock); 540 return (0); 541} 542 543static int 544cryptodevkey_cb(void *op) 545{ 546 struct cryptkop *krp = (struct cryptkop *) op; 547 |
503 wakeup(krp); | 548 wakeup_one(krp); |
504 return (0); 505} 506 507static int 508cryptodev_key(struct crypt_kop *kop) 509{ 510 struct cryptkop *krp = NULL; 511 int error = EINVAL; --- 33 unchanged lines hidden (view full) --- 545 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK); 546 if (!krp) 547 return (ENOMEM); 548 bzero(krp, sizeof *krp); 549 krp->krp_op = kop->crk_op; 550 krp->krp_status = kop->crk_status; 551 krp->krp_iparams = kop->crk_iparams; 552 krp->krp_oparams = kop->crk_oparams; | 549 return (0); 550} 551 552static int 553cryptodev_key(struct crypt_kop *kop) 554{ 555 struct cryptkop *krp = NULL; 556 int error = EINVAL; --- 33 unchanged lines hidden (view full) --- 590 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK); 591 if (!krp) 592 return (ENOMEM); 593 bzero(krp, sizeof *krp); 594 krp->krp_op = kop->crk_op; 595 krp->krp_status = kop->crk_status; 596 krp->krp_iparams = kop->crk_iparams; 597 krp->krp_oparams = kop->crk_oparams; |
598 krp->krp_crid = kop->crk_crid; |
|
553 krp->krp_status = 0; 554 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 555 556 for (i = 0; i < CRK_MAXPARAM; i++) 557 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 558 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 559 size = (krp->krp_param[i].crp_nbits + 7) / 8; 560 if (size == 0) --- 10 unchanged lines hidden (view full) --- 571 if (error) 572 goto fail; 573 error = tsleep(krp, PSOCK, "crydev", 0); 574 if (error) { 575 /* XXX can this happen? if so, how do we recover? */ 576 goto fail; 577 } 578 | 599 krp->krp_status = 0; 600 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 601 602 for (i = 0; i < CRK_MAXPARAM; i++) 603 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 604 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 605 size = (krp->krp_param[i].crp_nbits + 7) / 8; 606 if (size == 0) --- 10 unchanged lines hidden (view full) --- 617 if (error) 618 goto fail; 619 error = tsleep(krp, PSOCK, "crydev", 0); 620 if (error) { 621 /* XXX can this happen? if so, how do we recover? */ 622 goto fail; 623 } 624 |
625 kop->crk_crid = krp->krp_crid; /* device that did the work */ |
|
579 if (krp->krp_status != 0) { 580 error = krp->krp_status; 581 goto fail; 582 } 583 584 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 585 size = (krp->krp_param[i].crp_nbits + 7) / 8; 586 if (size == 0) --- 10 unchanged lines hidden (view full) --- 597 if (krp->krp_param[i].crp_p) 598 FREE(krp->krp_param[i].crp_p, M_XDATA); 599 } 600 free(krp, M_XDATA); 601 } 602 return (error); 603} 604 | 626 if (krp->krp_status != 0) { 627 error = krp->krp_status; 628 goto fail; 629 } 630 631 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 632 size = (krp->krp_param[i].crp_nbits + 7) / 8; 633 if (size == 0) --- 10 unchanged lines hidden (view full) --- 644 if (krp->krp_param[i].crp_p) 645 FREE(krp->krp_param[i].crp_p, M_XDATA); 646 } 647 free(krp, M_XDATA); 648 } 649 return (error); 650} 651 |
652static int 653cryptodev_find(struct crypt_find_op *find) 654{ 655 device_t dev; 656 657 if (find->crid != -1) { 658 dev = crypto_find_device_byhid(find->crid); 659 if (dev == NULL) 660 return (ENOENT); 661 strlcpy(find->name, device_get_nameunit(dev), 662 sizeof(find->name)); 663 } else { 664 find->crid = crypto_find_driver(find->name); 665 if (find->crid == -1) 666 return (ENOENT); 667 } 668 return (0); 669} 670 |
|
605/* ARGSUSED */ 606static int 607cryptof_poll( 608 struct file *fp, 609 int events, 610 struct ucred *active_cred, 611 struct thread *td) 612{ --- 157 unchanged lines hidden (view full) --- 770 /* falloc automatically provides an extra reference to 'f'. */ 771 f->f_flag = FREAD | FWRITE; 772 f->f_type = DTYPE_CRYPTO; 773 f->f_ops = &cryptofops; 774 f->f_data = fcr; 775 *(u_int32_t *)data = fd; 776 fdrop(f, td); 777 break; | 671/* ARGSUSED */ 672static int 673cryptof_poll( 674 struct file *fp, 675 int events, 676 struct ucred *active_cred, 677 struct thread *td) 678{ --- 157 unchanged lines hidden (view full) --- 836 /* falloc automatically provides an extra reference to 'f'. */ 837 f->f_flag = FREAD | FWRITE; 838 f->f_type = DTYPE_CRYPTO; 839 f->f_ops = &cryptofops; 840 f->f_data = fcr; 841 *(u_int32_t *)data = fd; 842 fdrop(f, td); 843 break; |
844 case CRIOFINDDEV: 845 error = cryptodev_find((struct crypt_find_op *)data); 846 break; 847 case CRIOASYMFEAT: 848 error = crypto_getfeat((int *)data); 849 break; |
|
778 default: 779 error = EINVAL; 780 break; 781 } 782 return (error); 783} 784 785static struct cdevsw crypto_cdevsw = { --- 41 unchanged lines hidden --- | 850 default: 851 error = EINVAL; 852 break; 853 } 854 return (error); 855} 856 857static struct cdevsw crypto_cdevsw = { --- 41 unchanged lines hidden --- |