📄 cryptodev.c
字号:
goto fail; }fail: if (krp) { kop->crk_status = krp->krp_status; for (i = 0; i < CRK_MAXPARAM; i++) { if (krp->krp_param[i].crp_p) kfree(krp->krp_param[i].crp_p); } kfree(krp); } return (error);}static struct csession *csefind(struct fcrypt *fcr, u_int ses){ struct csession *cse; dprintk("%s()\n", __FUNCTION__); list_for_each_entry(cse, &fcr->csessions, list) if (cse->ses == ses) return (cse); return (NULL);}static intcsedelete(struct fcrypt *fcr, struct csession *cse_del){ struct csession *cse; dprintk("%s()\n", __FUNCTION__); list_for_each_entry(cse, &fcr->csessions, list) { if (cse == cse_del) { list_del(&cse->list); return (1); } } return (0);} static struct csession *cseadd(struct fcrypt *fcr, struct csession *cse){ dprintk("%s()\n", __FUNCTION__); list_add_tail(&cse->list, &fcr->csessions); cse->ses = fcr->sesn++; return (cse);}struct csession *csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie, struct cryptoini *cria, struct csession_info *info){ struct csession *cse; dprintk("%s()\n", __FUNCTION__); cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL); if (cse == NULL) return NULL; memset(cse, 0, sizeof(struct csession)); INIT_LIST_HEAD(&cse->list); init_waitqueue_head(&cse->waitq); cse->key = crie->cri_key; cse->keylen = crie->cri_klen/8; cse->mackey = cria->cri_key; cse->mackeylen = cria->cri_klen/8; cse->sid = sid; cse->cipher = crie->cri_alg; cse->mac = cria->cri_alg; cse->info = *info; cseadd(fcr, cse); return (cse);}static intcsefree(struct csession *cse){ int error; dprintk("%s()\n", __FUNCTION__); error = crypto_freesession(cse->sid); if (cse->key) kfree(cse->key); if (cse->mackey) kfree(cse->mackey); kfree(cse); return(error);}static intcryptodev_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ struct cryptoini cria, crie; struct fcrypt *fcr = filp->private_data; struct csession *cse; struct csession_info info; struct session_op sop; struct crypt_op cop; struct crypt_kop kop; u_int64_t sid; u_int32_t ses; int feat, fd, error = 0; mm_segment_t fs; dprintk("%s()\n", __FUNCTION__); switch (cmd) { case CRIOGET: dprintk("%s(CRIOGET)\n", __FUNCTION__); fs = get_fs(); set_fs(get_ds()); fd = open("/dev/crypto", O_RDWR, 0); put_user(fd, (int *) arg); return(fd == -1 ? errno : 0); case CIOCGSESSION: dprintk("%s(CIOCGSESSION)\n", __FUNCTION__); memset(&crie, 0, sizeof(crie)); memset(&cria, 0, sizeof(cria)); memset(&info, 0, sizeof(info)); copy_from_user(&sop, (void*)arg, sizeof(sop)); switch (sop.cipher) { case 0: dprintk("%s(CIOCGSESSION) - no cipher\n", __FUNCTION__); break; case CRYPTO_NULL_CBC: info.blocksize = 4; info.minkey = 0; info.maxkey = 256; break; case CRYPTO_DES_CBC: info.blocksize = 8; info.minkey = 8; info.maxkey = 8; break; case CRYPTO_3DES_CBC: info.blocksize = 8; info.minkey = 24; info.maxkey = 24; break; case CRYPTO_BLF_CBC: info.blocksize = 8; info.minkey = 5; info.maxkey = 56; break; case CRYPTO_CAST_CBC: info.blocksize = 8; info.minkey = 5; info.maxkey = 16; break; case CRYPTO_SKIPJACK_CBC: info.blocksize = 8; info.minkey = 10; info.maxkey = 10; break; case CRYPTO_AES_CBC: info.blocksize = 16; info.minkey = 8; info.maxkey = 32; break; case CRYPTO_ARC4: info.blocksize = 1; info.minkey = 1; info.maxkey = 32; break; default: dprintk("%s(CIOCGSESSION) - bad cipher\n", __FUNCTION__); error = EINVAL; goto bail; } switch (sop.mac) { case 0: dprintk("%s(CIOCGSESSION) - no mac\n", __FUNCTION__); break; case CRYPTO_NULL_HMAC: info.keysize = 0; info.authsize = 12; break; case CRYPTO_MD5_HMAC: info.keysize = 16; info.authsize = 12; break; case CRYPTO_SHA1_HMAC: info.keysize = 20; info.authsize = 12; break; case CRYPTO_SHA2_HMAC: if (sop.mackeylen != 32 && sop.mackeylen != 48 && sop.mackeylen != 64) { dprintk("%s(CIOCGSESSION) - bad key\n", __FUNCTION__); error = EINVAL; goto bail; } info.keysize = sop.mackeylen; info.authsize = 12; break; case CRYPTO_RIPEMD160_HMAC: info.keysize = 20; info.authsize = 12; break; default: dprintk("%s(CIOCGSESSION) - bad mac\n", __FUNCTION__); error = EINVAL; goto bail; } if (info.blocksize) { crie.cri_alg = sop.cipher; crie.cri_klen = sop.keylen * 8; if (sop.keylen > info.maxkey || sop.keylen < info.minkey) { dprintk("%s(CIOCGSESSION) - bad key\n", __FUNCTION__); error = EINVAL; goto bail; } crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8, GFP_KERNEL); if (copy_from_user(crie.cri_key, sop.key, crie.cri_klen/8)) { dprintk("%s(CIOCGSESSION) - bad copy\n", __FUNCTION__); error = EFAULT; goto bail; } if (info.authsize) crie.cri_next = &cria; } if (info.authsize) { cria.cri_alg = sop.mac; cria.cri_klen = sop.mackeylen * 8; if (sop.mackeylen != info.keysize) { dprintk("%s(CIOCGSESSION) - mackeylen %d\n", __FUNCTION__, sop.mackeylen); error = EINVAL; goto bail; } if (cria.cri_klen) { cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL); if (copy_from_user(cria.cri_key, sop.mackey, cria.cri_klen / 8)) { dprintk("%s(CIOCGSESSION) - bad copy\n", __FUNCTION__); error = EFAULT; goto bail; } } } error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crypto_devsel); if (error) { dprintk("%s(CIOCGSESSION) - newsession %d\n", __FUNCTION__, error); goto bail; } cse = csecreate(fcr, sid, &crie, &cria, &info); if (cse == NULL) { crypto_freesession(sid); error = EINVAL; dprintk("%s(CIOCGSESSION) - csecreate failed\n", __FUNCTION__); goto bail; } sop.ses = cse->ses; if (copy_to_user((void*)arg, &sop, sizeof(sop))) { dprintk("%s(CIOCGSESSION) - bad copy\n", __FUNCTION__); error = EFAULT; }bail: if (error) { dprintk("%s(CIOCGSESSION) - bail %d\n", __FUNCTION__, error); if (crie.cri_key) kfree(crie.cri_key); if (cria.cri_key) kfree(cria.cri_key); } break; case CIOCFSESSION: dprintk("%s(CIOCFSESSION)\n", __FUNCTION__); get_user(ses, (uint32_t*)arg); cse = csefind(fcr, ses); if (cse == NULL) { error = EINVAL; goto bail; } csedelete(fcr, cse); error = csefree(cse); break; case CIOCCRYPT: dprintk("%s(CIOCCRYPT)\n", __FUNCTION__); copy_from_user(&cop, (void*)arg, sizeof(cop)); cse = csefind(fcr, cop.ses); if (cse == NULL) { error = EINVAL; goto bail; } error = cryptodev_op(cse, &cop); copy_to_user((void*)arg, &cop, sizeof(cop)); break; case CIOCKEY: dprintk("%s(CIOCKEY)\n", __FUNCTION__); copy_from_user(&kop, (void*)arg, sizeof(kop)); error = cryptodev_key(&kop); copy_to_user((void*)arg, &kop, sizeof(kop)); break; case CIOCASYMFEAT: dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__); error = crypto_getfeat(&feat); if (error) copy_to_user((void*)arg, &feat, sizeof(feat)); break; default: dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd); error = EINVAL; break; } return(-error);}static intcryptodev_open(struct inode *inode, struct file *filp){ struct fcrypt *fcr; dprintk("%s()\n", __FUNCTION__); if (filp->private_data) { printk("cryptodev: Private data already exists !\n"); return(0); } fcr = kmalloc(sizeof(*fcr), GFP_KERNEL); if (!fcr) { dprintk("%s() - malloc failed\n", __FUNCTION__); return(-ENOMEM); } memset(fcr, 0, sizeof(*fcr)); INIT_LIST_HEAD(&fcr->csessions); filp->private_data = fcr; return(0);}static intcryptodev_release(struct inode *inode, struct file *filp){ struct fcrypt *fcr = filp->private_data; struct csession *cse, *tmp; dprintk("%s()\n", __FUNCTION__); if (!filp) { printk("cryptodev: No private data on release\n"); return(0); } list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) { list_del(&cse->list); (void)csefree(cse); } kfree(fcr); filp->private_data = NULL; return(0);}struct file_operations cryptodev_fops = { .owner = THIS_MODULE, .open = cryptodev_open, .release = cryptodev_release, .ioctl = cryptodev_ioctl,};struct miscdevice cryptodev = { .minor = CRYPTODEV_MINOR, .name = "crypto", .fops = &cryptodev_fops,};static int __initcryptodev_init(void){ int rc; dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init); rc = misc_register (&cryptodev); if (rc) { printk(KERN_ERR "cryptodev: registeration of /dev/crypto failed\n"); return(rc); } return(0);}static void __exitcryptodev_exit(void){ dprintk("%s()\n", __FUNCTION__); misc_deregister(&cryptodev);}module_init(cryptodev_init);module_exit(cryptodev_exit);MODULE_LICENSE("BSD");MODULE_AUTHOR("davidm@snapgear.com");MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -