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

📄 bc_dev24.c

📁 加密解密,安全工具!很有意思的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* *	Copyright (c) 1994-1998 Jetico, Inc., Finland *	All rights reserved. * *	File:		driver/bc_dev.c * *	Description:	BestCrypt pseudo-device driver. * *	Scope:		BestCrypt pseudo-device driver * *	Platforms:	Linux * *	Ideas:		Igor M. Arsenin *			Serge A. Frolov *			Vitaliy G. Zolotarev * *	Author:		Nail R. Kaipov * *	Created:	10-Nov-1998 * *	Revision:	06-Aug-1999.	new strategy routine *			15-Sep-1999.	2.3.x kernels support *			11-Oct-1999.	strategy bugfix *			15-Dec-1999.	driver refinement *			21-Mar-2000.	bugfix for large blocks (v0.4b-2) *			15-Jun-2000.	partition support *			15-Nov-2000.	major rewrite. 2.4.0 version *			01-Feb-2001.	minor fixes. partitions cleanup. *			02-May-2001.	SMP bugfix, /proc update *			06-Jun-2001.	writing magic in bc_clr_fd *			10-Oct-2001.	bc_lock_dev() fixed *			04-Nov-2003.	64-bit IV added. * *******************************************************************/#ifndef EXPORT_SYMTAB#define EXPORT_SYMTAB#endif#include "bc_cfg.h"#include <linux/module.h>#include <linux/fs.h>			/* inode et al            */#include <linux/proc_fs.h>		/* proc_fs support        */#include <linux/devfs_fs_kernel.h>	/* devfs_fs support       */#include <linux/file.h>			/* fget()/fput() pair     */#include <linux/vmalloc.h>		/* vmalloc()              */#include <asm/uaccess.h>		/* put_user()             */#include <asm/atomic.h>			/* atomic operations      */#include <linux/hdreg.h>		/* hd_geometry            */#include "bc_types.h"			/* bc types               */#include "bc_ioctl.h"			/*           ioctl codes  */#include "bc_mgr.h"#include "bc_dev.h"			/* bc types        codes  */#define DEVICE_OFF(dev)#include <linux/blk.h>#define __KERNEL_SYSCALLS__#include <linux/unistd.h>#ifndef GFP_NOIO#define GFP_NOIO GFP_BUFFER#endifstatic int		bc_devices = DEFAULT_BC_DEVICES;static int		bc_partitions = DEFAULT_BC_PARTITIONS;static int		bc_minor_shift = 0;struct bc_device	*bc_dev;		/* bc devices' array  */static struct bc_disk   *bc_dsk;		/* bc disks array     */static int		*bc_sizes;		/**/static int		*bc_blksizes;		/**/static struct hd_struct	*bc_hd;			/**//* pid control table support */#define BC_PID_SIZE 64static pid_t            	*bc_pid_table;static int			bc_pid_size;static int			bc_pid_next;static struct semaphore 	bc_pid_sema;static struct timer_list	bc_pid_timer;static devfs_handle_t		bc_hdevfs;static struct gendisk		bc_gendisk;static struct proc_dir_entry    *proc_bcrypt;static DECLARE_WAIT_QUEUE_HEAD(wait_open);static DECLARE_WAIT_QUEUE_HEAD(wait_bc);EXPORT_SYMBOL(register_bc_algo);EXPORT_SYMBOL(unregister_bc_algo);MODULE_PARM(bc_devices, "i");MODULE_PARM_DESC(bc_devices, "Max. number of devices (1-256).");MODULE_PARM(bc_partitions, "i");MODULE_PARM_DESC(bc_partitions, "Max. partitions per device (0-63).");MODULE_AUTHOR("Jetico, Inc.");MODULE_DESCRIPTION("BestCrypt encrypted block device driver.");#ifdef MODULE_LICENSEMODULE_LICENSE("Jetico, Inc.");#endifstatic int     bc_ioctl     (struct inode *,  struct file *, unsigned int, unsigned long);static int     bc_open      (struct inode *,  struct file *);static int     bc_release   (struct inode *,  struct file *);/*static struct file_operations bc_fops;*/static struct block_device_operations bc_bdops = {	ioctl  :bc_ioctl,	open   :bc_open,	release:bc_release};/*-----------------------------------------------------------*/static inline struct bc_device *get_bcdev(kdev_t dev){	int 	mn = MINOR(dev);	if (MAJOR_NR == MAJOR(dev) && MAX_MINORS > MINOR(dev)) {		mn >>= bc_minor_shift; 			if (0 <= mn && bc_devices > mn)			return bc_dev+mn;	}	return NULL; /* -ENODEV error */}static inline struct bc_disk *get_bcdsk(kdev_t dev) {	int	mn = MINOR(dev);	if (MAJOR_NR == MAJOR(dev) && MAX_MINORS > MINOR(dev)) {		if (0 <= mn && bc_devices * bc_partitions > mn)			return bc_dsk+mn;	}	return NULL;	}static inline int is_parent(struct bc_disk *bd) {	if (NULL != bd)		return !(bd->bd_number & ((1 << bc_minor_shift) - 1));	return 0;}static inline void reset_dev(struct bc_device *bc){		int             i, j;	if (NULL == bc)		return;	bc->bc_offset = 0L;	bc->bc_start_sector = 0L;	bc->bc_num_sectors  = 0L;	bc->bc_dev    = 0;	bc->bc_key    = 0;	bc->bc_alg    = NULL;	bc->bc_file   = NULL;	bc->bc_dentry = NULL;	atomic_set(&bc->bc_pending, 0);	spin_lock_init(&bc->bc_lock);	init_MUTEX_LOCKED(&bc->bc_thread);	init_MUTEX_LOCKED(&bc->bc_run);	bc->bc_bh     = NULL;	bc->bc_bhtail = NULL;	bc->bc_gfpmask = 0;	bc->bc_save_fops = NULL;	bc->bc_activity = 0;	memset(&bc->bc_flags, 0, sizeof(bc->bc_flags));	if (NULL != bc->bc_buffer)		vfree(bc->bc_buffer);	bc->bc_buffer = NULL;	i = bc->bc_number << bc_minor_shift;	j = i + (1 << bc_minor_shift);	memset(&bc_dsk[i], 0, (j-i) * sizeof(struct bc_disk));	for (; i < j; i++)		bc_dsk[i].bd_number = i;}/*-----------------------------------------------------------*/static inline int bc_find_pid(pid_t pid) {	register int i;	for (i = 0; i < bc_pid_next; i++)		if (pid == bc_pid_table[i])			return i;	return -1;}static int bc_find_pid_safe(pid_t pid){		int i;	down(&bc_pid_sema);	i = bc_find_pid(pid);	up(&bc_pid_sema);	return i;}static int bc_add_pid(pid_t pid) {	pid_t	*tmp;		down(&bc_pid_sema);	if (bc_find_pid(pid) > -1) {		up(&bc_pid_sema);		return 0;	}	if (bc_pid_next < bc_pid_size) {		bc_pid_table[bc_pid_next] = pid;		bc_pid_next++;	} else {		tmp = kmalloc((bc_pid_size+BC_PID_SIZE) * sizeof(pid_t), GFP_KERNEL);		if (NULL == tmp) {			up(&bc_pid_sema);			return -ENOMEM;		}		memcpy(bc_pid_table, tmp, bc_pid_size * sizeof(pid_t));		kfree(bc_pid_table);		bc_pid_table = tmp;		bc_pid_size += BC_PID_SIZE;		bc_pid_table[bc_pid_next] = pid;		bc_pid_next++;	}	if (1 == bc_pid_next) {		bc_pid_timer.expires = jiffies + 5 * HZ;		add_timer(&bc_pid_timer);	}	up(&bc_pid_sema);	return 0;}static int bc_del_pid(pid_t pid) {	int	i;	pid_t	*tmp;	down(&bc_pid_sema);	i = bc_find_pid(pid);	if (0 > i) {		up(&bc_pid_sema);		return 0;	}	bc_pid_next--;	if (bc_pid_next)	        bc_pid_table[i] = bc_pid_table[bc_pid_next];	bc_pid_table[bc_pid_next] = 0;			if (bc_pid_size-bc_pid_next > 2*BC_PID_SIZE) {		tmp = kmalloc((bc_pid_size-BC_PID_SIZE) * sizeof(pid_t), GFP_KERNEL);		if (NULL == tmp) {			up(&bc_pid_sema);			return 0;		}		bc_pid_size -= BC_PID_SIZE;		memcpy(bc_pid_table, tmp, bc_pid_size * sizeof(pid_t));		kfree(bc_pid_table);		bc_pid_table = tmp;	}	up(&bc_pid_sema);	return 0;}static void bc_pid_timer_proc(unsigned long unused) {	register int i;	down(&bc_pid_sema);#ifdef CONFIG_SMP	write_lock_irq(&tasklist_lock);#endif		for (i = 0; i < bc_pid_next; i++) {		if (NULL == find_task_by_pid(bc_pid_table[i])) {			bc_pid_next--;			if (bc_pid_next)				bc_pid_table[i] = bc_pid_table[bc_pid_next];			bc_pid_table[bc_pid_next] = 0;			i--;		}	}#ifdef CONFIG_SMP        write_unlock_irq(&tasklist_lock);#endif		if (bc_pid_next) {		bc_pid_timer.expires = jiffies + 5 * HZ;		add_timer(&bc_pid_timer);	}	up(&bc_pid_sema);}/*-----------------------------------------------------------*/static int bc_thread(void *data){	struct bc_device   *bc = (struct bc_device *)data;	struct buffer_head *bh;	struct bc_disk     *bd;	struct file	   *file;	size_t		   len, ret, size;	loff_t		   pos, sec;	char		   *dst, *buf = NULL;	u16		   iv[4];	u64		   iv64, iv64le;	mm_segment_t	   fs;	int		   i, uptodate, rw;	daemonize();	sprintf(current->comm, "bcrypt%d", bc->bc_number);#ifdef SCHED_OTHER	spin_lock_irq(&current->sigmask_lock);	sigfillset(&current->blocked);	flush_signals(current);	spin_unlock_irq(&current->sigmask_lock);	current->policy = SCHED_OTHER;#else	spin_lock_irq(&current->sighand->siglock);	sigfillset(&current->blocked);	flush_signals(current);	spin_unlock_irq(&current->sighand->siglock);	current->policy = SCHED_NORMAL;#endif#ifdef _NICE_PRESENT_	current->nice = -20;#else	set_user_nice(current,  -20l);#endif	#ifdef PF_NOIO /* 2.4.17 kludge */	current->flags |= PF_NOIO;#endif 	spin_lock_irq(&bc->bc_lock);	bc->bc_flags.active = 1;	atomic_inc(&bc->bc_pending);	spin_unlock_irq(&bc->bc_lock);	up(&bc->bc_thread);	while (1) {		down_interruptible(&bc->bc_run);		i = atomic_read(&bc->bc_pending);		if (i == 0)			break;		spin_lock_irq(&bc->bc_lock);		bh = bc->bc_bh;		if (NULL == bh) {			spin_unlock_irq(&bc->bc_lock);			continue;		}		if (bc->bc_bhtail == bh)			bc->bc_bhtail = NULL;		bc->bc_bh = bh->b_reqnext;		bh->b_reqnext = NULL;		spin_unlock_irq(&bc->bc_lock);		uptodate = 0;				bd = get_bcdsk(bh->b_rdev);		if (!bd->bd_flags.configured && bc->bc_flags.busy) {			bd->bd_offset = bc->bc_offset +			(((loff_t)bc_gendisk.part[bd->bd_number].start_sect) << 9);		}		sec   = (loff_t)bh->b_rsector + bc->bc_start_sector;		pos   = sec * 512 + bd->bd_offset;		len   = bh->b_size;		dst   = bh->b_data;		file  = bc->bc_file;		iv[0] = iv[1] = iv[2] = iv[3] = sec & 0xFFFF;		iv64  = sec + 1;		bc->bc_activity = 1;		rw = !!test_and_clear_bit(BH_Dirty, &bh->b_state);		if (READ == rw) {			fs = get_fs();			set_fs(KERNEL_DS);			ret = file->f_op->read(file, dst, len, &pos);			set_fs(fs);			if (ret != len) {				printk(KERN_ERR "bc: read error wanted %ld, read %ld\n",					(unsigned long)len, (unsigned long)ret);				goto error_out;			}			if (bc->bc_flags.iv_64bit) {				iv64le = __cpu_to_le64(iv64);				bc->bc_alg->decrypt(bc->bc_key, (char *)(&iv64le), dst, dst, len);			} else {				bc->bc_alg->decrypt(bc->bc_key, (char *)iv, dst, dst, len);			}		} else {			buf = bc->bc_buffer;			size = BC_BUFFER_SIZE;			while (len > 0) {				if (size > len)					size = len;				if (bc->bc_flags.iv_64bit) {					iv64le = __cpu_to_le64(iv64);					bc->bc_alg->encrypt(bc->bc_key, (char *)(&iv64le), dst, buf, size);				} else {					bc->bc_alg->encrypt(bc->bc_key, (char *)iv, dst, buf, size);				}				fs = get_fs();				set_fs(KERNEL_DS);				ret = file->f_op->write(file, buf, size, &pos);				set_fs(fs);				if (ret != size) {					printk(KERN_ERR "bc: write error wanted %ld, wrote %ld\n",						(unsigned long)size, (unsigned long)ret);					goto error_out;				}				if (bc->bc_flags.iv_64bit) {					iv64 += BC_BUFFER_SIZE/512;				} else {					iv[0] = ((int)iv[0] + BC_BUFFER_SIZE/512) & 0xFFFF;					iv[3] = iv[2] = iv[1] = iv[0];				}				dst += size;				len -= size;			}		}		uptodate = 1;error_out:		bh->b_end_io(bh, uptodate);		if (atomic_dec_and_test(&bc->bc_pending))		    break;	}	up(&bc->bc_thread);	return 0;}static int bc_make_request(request_queue_t *q, int rw, struct buffer_head *bh){	int rw_ahead;	struct bc_device *bc;	struct bc_disk   *bd;		if (!buffer_locked(bh))		BUG();			rw_ahead = 0;	bc = get_bcdev(bh->b_rdev);	bd = get_bcdsk(bh->b_rdev);	if (!bc || !bd || !bc->bc_dentry || !bc->bc_dentry->d_inode) {		printk(KERN_ERR "bc: invalid device.\n");		goto error_out;	}	if (!bd->bd_flags.configured && !bc->bc_flags.busy) {		printk(KERN_ERR "bc: device not configured yet.\n");		goto error_out;	}	if (WRITE == rw) {		if (bc->bc_flags.readonly) {			printk(KERN_ERR "bc: attempt to write on readonly device.\n");			goto error_out;		}	} else if (READA == rw) {		rw = READ;		rw_ahead = 1;	} else if (READ != rw) {		printk(KERN_ERR "bc: unknown command (%d).\n", rw);		goto error_out;	}		spin_lock_irq(&bc->bc_lock);		if (!bc->bc_flags.active) {		spin_unlock_irq(&bc->bc_lock);		goto error_out;	}	atomic_inc(&bc->bc_pending);//	spin_unlock_irq(&bc->bc_lock);	#ifdef CONFIG_HIGHMEM	bh = create_bounce(rw, bh);#endif		if (WRITE == rw)		set_bit(BH_Dirty, &bh->b_state);//	spin_lock_irq(&bc->bc_lock);	if (bc->bc_bhtail)	bc->bc_bhtail->b_reqnext = bh;	else			bc->bc_bh = bh;	bc->bc_bhtail = bh;	spin_unlock_irq(&bc->bc_lock);		up(&bc->bc_run);	return 0;error_out:	buffer_IO_error(bh);	return 0;}/*-- end of strategy routine --------------------------------*//*-- fops functions -----------------------------------------*/static int bc_open(struct inode *inode, struct file *file){	struct bc_device *bc;	if (NULL == inode)		    return -EINVAL;	MOD_INC_USE_COUNT;	bc = get_bcdev(inode->i_rdev);	if (NULL == bc) {		printk(KERN_ERR "bc_open: invalid device (%d, %d).\n",

⌨️ 快捷键说明

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