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

📄 bc_dev22.c

📁 BestCrypt开源加密原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*-- algorithm driver ioctls --------------------------------*/static int bc_vrfy_alg(struct bc_alg *arg){	struct bc_alg		query;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC || 	   !get_bc_algo(query.alg_id, &query.alg_module[0])) 		return -EINVAL;	return 0;	}static int bc_make_key(struct bc_key *arg){	struct bc_key		query;	struct bc_algorithm	*bc_alg;	int			error;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC || !query.key || !query.pool) 		return -EINVAL;	bc_alg = get_bc_algo(query.alg_id, &query.alg_module[0]);	if (!bc_alg) 		return -EINVAL;	/* WARNING!!! using user mode memory areas */	error = bc_alg->make_key(query.key, query.key_len, query.pool, &query.key_handle);	if (error)		return error;		if (copy_to_user(&arg->key_handle, &query.key_handle, sizeof(KEY_HANDLE)))		return -EFAULT;	return 0;	}static int bc_free_key(struct bc_key *arg){	struct bc_key		query;	struct bc_algorithm	*bc_alg;	int			error;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC) 		return -EINVAL;	bc_alg = get_bc_algo(query.alg_id, NULL);	if (!bc_alg) 		return -EINVAL;	error = bc_alg->free_key(query.key_handle);	return error;}static int bc_process(struct bc_block *arg, int operation){	struct bc_block		query;	struct bc_algorithm	*bc_alg;	int			error;	char			*buffer;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC || 	   !query.buffer || 	   query.buffer_len > MAX_BLOCK_SIZE) 		return -EINVAL;		bc_alg = get_bc_algo(query.alg_id, NULL);	if (!bc_alg) 		return -EINVAL;	buffer = vmalloc(query.buffer_len);	if (!buffer) 		return -ENOMEM;		if (copy_from_user(buffer, query.buffer, query.buffer_len)) {		error = -EFAULT;		goto error_out;	}	switch (operation) {	case BC_ENCRYPT_BLOCK:		error = bc_alg->encrypt(query.key_handle, &query.iv[0], 				buffer, buffer, query.buffer_len);		break;	case BC_DECRYPT_BLOCK:		error = bc_alg->decrypt(query.key_handle, &query.iv[0], 				buffer, buffer, query.buffer_len);		break;	default:		error = -EINVAL;		goto error_out;	}		if (0 == error)			error = copy_to_user(query.buffer, buffer, query.buffer_len);error_out:	if (buffer) {		memset(buffer, 0, query.buffer_len);		vfree(buffer);		buffer = NULL;	}	return error;}/*--------------------------------------------------------------------*/static int blkgetsize(struct bc_disk *bd, struct bc_device *bc, long *arg) {	if (!bc->bc_dentry)			return -ENXIO;	if (!arg)		return -EINVAL;	put_user(bc_sizes[bd->bd_number] << 1, arg);	return 0;}static int hdio_getgeo(struct bc_disk *bd, struct bc_device *bc, struct hd_geometry *geo) {	unsigned long           i, j, size;        unsigned char           head, sect;        unsigned short          cyl;	if (NULL == bc->bc_dentry)                return -ENXIO;	if (NULL == geo)		return -EINVAL;	size = bc_sizes[bd->bd_number] << 1;        for (i = -1, j = size; j > 0; j >>= 1, i++);		if (0 > i)	        return -ENXIO;        if (16 > i) {                sect = 1;                head = 1;                cyl  = size;        } else if (23 > i) {                sect = 1;                head = 1 << (i-15);                cyl  = size >> (i-15);        } else {                sect = 1 << (i-22);                head = 1 << 7;                cyl  = size >> (i-15);        }	put_user (head, (u8 *)&geo->heads);        put_user (sect, (u8 *)&geo->sectors);        put_user (cyl, (u16 *)&geo->cylinders);        put_user (0,   (u32 *)&geo->start);	return 0;}/*====================================================================*/static int bc_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg){	struct bc_device *bc;	struct bc_disk   *bd;	int error;		if (!inode) 		return -EINVAL;	bc = get_bcdev(inode->i_rdev);        if (NULL == bc) {		error = save_fops.ioctl(inode, file, cmd, arg);		if (max_loop) {			if (save_blksize)				memcpy(bc_sizes, save_blksize, (max_loop)*sizeof(int));			if (save_blksize_size)				memcpy(bc_blksizes, save_blksize_size, (max_loop)*sizeof(int));		}		return error;	}	bd = get_bcdsk(inode->i_rdev);	error = -EINVAL;	down(&bc->bc_control);	switch (cmd) {	BC_HANDLER("get_info", BC_GET_INFO,      bc_get_info(bd, bc, (struct bc_info*)  arg));	BC_HANDLER("set_fd  ", BC_SET_FD,        bc_set_fd  (bd, bc, inode->i_rdev, (struct bc_file64 *) arg));	BC_HANDLER("clr_fd  ", BC_CLR_FD,        bc_clr_fd  (bd, bc));	BC_HANDLER("lock_dev", BC_LOCK_DEV,      bc_lock_dev(bd, bc, inode->i_rdev, 1));	BC_HANDLER("ulck_dev", BC_UNLOCK_DEV,    bc_lock_dev(bd, bc, inode->i_rdev, 0));	BC_HANDLER("frc_ulck", BC_FORCE_UNLOCK,  bc_force_unlock(bd, bc, inode->i_rdev));	BC_HANDLER("get_priv", BC_GET_PRIV,      bc_get_priv(arg));	BC_HANDLER("chk_actv", BC_CHECK_ACTIVITY,bc_check_activity(bc, inode->i_rdev, (long *)arg));	BC_HANDLER("blkgetsz", BLKGETSIZE,       blkgetsize (bd, bc, (long *)arg));	BC_HANDLER("hdio_geo", HDIO_GETGEO,      hdio_getgeo(bd, bc, (struct hd_geometry *) arg));	BC_HANDLER("rrd_part", BLKRRPART,        scan_device(bd, bc));	BC_HANDLER("check_fd", BC_CHECK_FD,      bc_check   ((struct bc_check*) arg));	BC_HANDLER("vrfy_alg", BC_VERIFY_ALG,    bc_vrfy_alg((struct bc_alg*)   arg));	BC_HANDLER("make_key", BC_MAKE_KEY,      bc_make_key((struct bc_key*)   arg));	BC_HANDLER("free_key", BC_FREE_KEY,      bc_free_key((struct bc_key*)   arg));	BC_HANDLER("encr_blk", BC_ENCRYPT_BLOCK, bc_process ((struct bc_block*) arg, BC_ENCRYPT_BLOCK));	BC_HANDLER("decr_blk", BC_DECRYPT_BLOCK, bc_process ((struct bc_block*) arg, BC_DECRYPT_BLOCK));	}	up(&bc->bc_control);	return error;}/*====================================================================*/int proc_bc_stat(char *page, char **start, off_t off, int count, int *eof, void *data) {	int len;	char *p = page;			p += sprintf(p, "# BestCrypt system v" BC_VERSION_STRING ":\n");	p += sprintf(p, "# Compiled at "__TIME__ " " __DATE__"\n");	p += sprintf(p, "devices     %d\n", bc_devices);	p += sprintf(p, "partitions  %d\n", bc_partitions);	p += sprintf(p, "major       %d\n", MAJOR_NR);	p += sprintf(p, "minor       %d\n", bc_start_minor);	len = p - page;	if (len <= off+count)		*eof = 1;	*start = page + off;	len -= off;	if (len > count)		len = count;	if (len < 0)		len = 0;	return len;}/*-----------------------------------------------------------*/int init_module(void) {	int	max_devices, rc, error;	struct file_operations *fops;	struct inode		fake_inode;	bc_start_minor = 128;	if ((bc_devices > MAX_MINORS-bc_start_minor) || (bc_devices <= 0))		bc_devices = DEFAULT_BC_DEVICES;	if (bc_partitions > 1) {		for (bc_minor_shift = 0; bc_partitions; bc_minor_shift++)			bc_partitions >>= 1;		bc_partitions = 1 << bc_minor_shift;		while (bc_start_minor & (bc_partitions - 1)) {		    bc_partitions >>= 1;		    bc_minor_shift--;		}		if ((MAX_MINORS-bc_start_minor)/bc_partitions < bc_devices)			bc_devices = (MAX_MINORS-bc_start_minor)/bc_partitions;	} 		if (bc_partitions < 2) {		bc_partitions = 1;		bc_minor_shift = 0;	}		bc_devices = DEFAULT_BC_DEVICES;	bc_partitions = 1;	bc_minor_shift = 0;		max_devices = bc_devices * bc_partitions;				printk(KERN_INFO "Loading BestCrypt v%s (%d[%d] devices)...\n", 		BC_VERSION_STRING,		bc_devices, bc_partitions); 			memset(&fake_inode, 0, sizeof(struct inode));	fake_inode.i_rdev = MKDEV(MAJOR_NR, bc_start_minor);	fops = get_blkfops(MAJOR_NR);	if (NULL == fops) {		if (0 > register_blkdev(MAJOR_NR, DEVICE_NAME, &bc_fops)) {			printk(KERN_ERR "bc: unable to get major number %d\n", MAJOR_NR);			return -EIO;		}	} else {		if (-ENODEV != fops->open(&fake_inode, NULL)) {			fops->release(&fake_inode, NULL);			printk(KERN_ERR "bc: already loaded\n");			return -EIO;		}		for (max_loop = 255; max_loop >= 0; max_loop--) {			fake_inode.i_rdev = MKDEV(MAJOR_NR, max_loop);			if (-ENODEV != fops->open(&fake_inode, NULL))				break;		}		if ((max_loop < 0) || (max_loop >= bc_start_minor)) {			printk(KERN_ERR "bc: initialization error\n");			return -EIO;		}		max_loop++;				memcpy(&save_fops, fops, sizeof(struct file_operations));		memcpy(fops, &bc_fops, sizeof(struct file_operations));		save_request_fn = BC_GET_REQUEST_FN(MAJOR_NR);		save_blksize = blk_size[MAJOR_NR];		save_blksize_size = blksize_size[MAJOR_NR];	}		bc_dev = kmalloc(bc_devices  * sizeof(struct bc_device), GFP_KERNEL);	bc_dsk = kmalloc(max_devices * sizeof(struct bc_disk),   GFP_KERNEL);	bc_buffers[0].ptr = vmalloc(BC_BUFFERS * BC_BUFFER_SIZE);	bc_pid_table = kmalloc(BC_PID_SIZE * sizeof(pid_t), GFP_KERNEL);	if (NULL == bc_dev ||	    NULL == bc_dsk ||	    NULL == bc_pid_table ||	    NULL == bc_buffers[0].ptr) {		error = -ENOMEM;		goto error_out;	}	memset(bc_sizes,    0, sizeof(bc_sizes));	memset(bc_blksizes, 0, sizeof(bc_blksizes));	memset(bc_hd,       0, sizeof(bc_hd));	memset(bc_dev,      0, bc_devices * sizeof(struct bc_device));	memset(bc_dsk,      0, max_devices * sizeof(struct bc_disk));	memset(bc_pid_table, 0, BC_PID_SIZE * sizeof(pid_t));	bc_pid_size = BC_PID_SIZE;	bc_pid_next = 0;	bc_pid_sema = MUTEX;	init_timer(&bc_pid_timer);	bc_pid_timer.function = bc_pid_timer_proc;	for (rc = 0; rc < bc_devices; rc++) {		bc_dev[rc].bc_number = rc;		bc_dev[rc].bc_control = MUTEX;	}	for (rc = 0; rc < max_devices; rc++) {		bc_dsk[rc].bd_number = rc + bc_start_minor;	}	for (rc = 0; rc < BC_BUFFERS; rc++) {		bc_buffers[rc].ptr = bc_buffers[0].ptr + rc * BC_BUFFER_SIZE;		atomic_set(&bc_buffers[rc].count, 1);	}	if (0 > init_bc_algo()) {		error = -EINVAL; 		goto error_out;	}#ifdef CONFIG_PROC_FS			proc_bcrypt = create_proc_entry("bcrypt", S_IFDIR, &proc_root);	if (proc_bcrypt) {		proc_tmp = create_proc_entry(DEVICE_CONF, S_IFREG | S_IRUGO, proc_bcrypt);		if (proc_tmp)		    proc_tmp->read_proc = proc_bc_conf;		proc_tmp = create_proc_entry(DEVICE_STAT, S_IFREG | S_IRUGO, proc_bcrypt);		if (proc_tmp)		    proc_tmp->read_proc = proc_bc_stat;	} #endif	if (max_loop) {		if (blk_size[MAJOR_NR])			memcpy(bc_sizes, blk_size[MAJOR_NR], (max_loop)*sizeof(int));		if (blksize_size[MAJOR_NR])			memcpy(bc_blksizes, blksize_size[MAJOR_NR], (max_loop)*sizeof(int));	}	BC_GET_REQUEST_FN(MAJOR_NR) = do_bc_request;	blk_size[MAJOR_NR] = bc_sizes;	blksize_size[MAJOR_NR] = bc_blksizes;		bc_gendisk.major        = MAJOR_NR;	bc_gendisk.major_name   = DEVICE_NAME;	bc_gendisk.minor_shift  = bc_minor_shift;	bc_gendisk.max_p        = 1 << bc_minor_shift;	bc_gendisk.max_nr       = (MAX_MINORS - bc_start_minor) >> bc_minor_shift;	bc_gendisk.init         = NULL;	bc_gendisk.part         = bc_hd;	bc_gendisk.sizes        = bc_sizes;	bc_gendisk.nr_real      = 0;	bc_gendisk.real_devices = NULL;	bc_gendisk.next         = gendisk_head;	gendisk_head            = &bc_gendisk;	return 0;	error_out:	if (NULL == fops) {		unregister_blkdev(MAJOR_NR, DEVICE_NAME);		} else {		memcpy(fops, &save_fops, sizeof(struct file_operations));	}	if (bc_dev) kfree(bc_dev);	if (bc_dsk) kfree(bc_dsk);	if (bc_pid_table) kfree(bc_pid_table);	if (bc_buffers[0].ptr) vfree(bc_buffers[0].ptr);	bc_dev = NULL;	bc_dsk = NULL;	bc_buffers[0].ptr = NULL;	return error;}void cleanup_module(void) {	struct file_operations	*fops;	struct gendisk		**gdp;	struct inode		fake_inode;	down(&bc_pid_sema);	del_timer(&bc_pid_timer);	up(&bc_pid_sema);	if (max_loop) {		fops = get_blkfops(MAJOR_NR);		memcpy(fops, &save_fops, sizeof(struct file_operations));		BC_GET_REQUEST_FN(MAJOR_NR) = save_request_fn;		memcpy(save_blksize, blk_size[MAJOR_NR], max_loop*sizeof(int));		memcpy(save_blksize_size, blksize_size[MAJOR_NR], max_loop*sizeof(int));		blk_size[MAJOR_NR] = save_blksize;		blksize_size[MAJOR_NR] = save_blksize_size;			memset(&fake_inode, 0, sizeof(struct inode));		fake_inode.i_rdev = MKDEV(MAJOR_NR, max_loop-1);		fops->release(&fake_inode, NULL);		} else {		if (unregister_blkdev(MAJOR_NR, DEVICE_NAME) != 0) 			printk(KERN_ERR "bc: cleanup failed.\n");	}	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))		if (*gdp == &bc_gendisk)			break;	if (!*gdp)		printk(KERN_ERR "bc: entry in disk chain missing.\n");	else		*gdp = (*gdp)->next;#ifdef CONFIG_PROC_FS			if (proc_bcrypt) {		remove_proc_entry(DEVICE_CONF, proc_bcrypt);		remove_proc_entry(DEVICE_STAT, proc_bcrypt);	}	remove_proc_entry("bcrypt", &proc_root);#endif	if (bc_dev) kfree(bc_dev);	if (bc_dsk) kfree(bc_dsk);	if (bc_pid_table) kfree(bc_pid_table);	if (bc_buffers[0].ptr) vfree(bc_buffers[0].ptr);	bc_dev = NULL;	bc_dsk = NULL;	bc_buffers[0].ptr = NULL;}/*-- end of device registration stuff -----------------------*/	char bc_dev22_c[]="$Id: bc_dev22.c,v 1.18 2006/03/07 05:40:24 nail Rel-1.6-5 $";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -