⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cryptodev.c

📁 linux下基于加密芯片的加密设备
💻 C
📖 第 1 页 / 共 2 页
字号:
			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 + -