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

📄 bc_dev22.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) *			02-May-2001.	SMP bugfix, /proc update *			06-Jun-2001.	writing magic in bc_clr_fd * *******************************************************************/#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>		/* inode et al            */#include <linux/vmalloc.h>		/* vmalloc()              */#include <linux/kernel.h>		/* printk()               */#include <asm/uaccess.h>		/* put_user()             */#include <asm/atomic.h>			/* atomic operations      */#include <linux/hdreg.h>		/* hd_geometry            */#include <linux/file.h>			/* inode et al            */#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>static int              bc_devices = DEFAULT_BC_DEVICES;static int		bc_partitions = DEFAULT_BC_PARTITIONS;static int		bc_minor_shift = 0;static int		bc_start_minor = 128;static struct bc_device	*bc_dev;static struct bc_disk	*bc_dsk;static struct gendisk	bc_gendisk;static int		bc_sizes	[MAX_MINORS];static int		bc_blksizes	[MAX_MINORS];static struct hd_struct bc_hd		[MAX_MINORS];struct request		*BC_CURRENT = NULL;static struct wait_queue *wait_open = 0;/* 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;struct bc_buffer_desc {	atomic_t	count;	char		*ptr;} bc_buffers[BC_BUFFERS];static ssize_t bc_read      (struct file *,   char *, size_t, loff_t *);static ssize_t bc_write     (struct file *,   const char *, size_t, loff_t *);static 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 int     dummy_ioctl  (struct inode *i, struct file *f, u_int cmd, u_long arg) { return -ENODEV; }static int     dummy_open   (struct inode *i, struct file *f) { return -ENODEV; }static int     dummy_release(struct inode *i, struct file *f) { return -ENODEV; }static int     *save_blksize;static int     *save_blksize_size;static int     max_loop;static struct  proc_dir_entry    *proc_bcrypt, *proc_tmp;#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,32))#define BC_GET_REQUEST_FN(_MAJOR_) blk_dev[_MAJOR_].request_queue.request_fnstatic void    dummy_request_fn  (request_queue_t *rq) { return; }static void    (*save_request_fn)(request_queue_t *rq) = dummy_request_fn;#else#define BC_GET_REQUEST_FN(_MAJOR_) blk_dev[_MAJOR_].request_fnstatic void    dummy_request_fn(void) { return; }static void    (*save_request_fn)(void) = dummy_request_fn;#endifstatic struct file_operations save_fops = {	read   :block_read,	write  :block_write,	ioctl  :dummy_ioctl,	open   :dummy_open,	release:dummy_release,	fsync  :block_fsync};static struct file_operations bc_fops = {	read   :bc_read,	write  :bc_write,	ioctl  :bc_ioctl,	open   :bc_open,	release:bc_release,	fsync  :block_fsync};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-127).");MODULE_PARM(bc_partitions, "i");MODULE_PARM_DESC(bc_partitions, "Max. number of partitions per device (0-31).");MODULE_AUTHOR("Jetico, Inc.");MODULE_DESCRIPTION("BestCrypt encrypted block device driver.");/*-----------------------------------------------------------*/static inline struct bc_device *get_bcdev(kdev_t dev){	int	mn = MINOR(dev) - bc_start_minor;		if ((MAJOR_NR == MAJOR(dev)) && (MAX_MINORS > MINOR(dev))) {	    mn >>=bc_minor_shift;	    if ((mn >= 0) && (mn < bc_devices))		return bc_dev+mn;	}	return NULL;}static inline struct bc_disk *get_bcdsk(kdev_t dev){	int	mn = MINOR(dev) - bc_start_minor;		if ((MAJOR_NR == MAJOR(dev)) && (MAX_MINORS > MINOR(dev))) {	    if ((mn >= 0) && (mn < bc_devices*bc_partitions))		return bc_dsk+mn;	}	return NULL;}static inline int is_parent(struct bc_disk *bd){	if (NULL != bd)		return !((bd->bd_number-bc_start_minor) & ((1 << bc_minor_shift) - 1));	return 0;}static inline void reset_dev(struct bc_device *bc){	int            i, j;	struct bc_disk *bd;		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;	bc->bc_activity = 0;	memset(&bc->bc_flags, 0, sizeof(bc->bc_flags));		bd = &bc_dsk[bc->bc_number << bc_minor_shift];	for (i = 0; i < 1 << bc_minor_shift; i++) {		j = bd->bd_number;		memset(bd, 0, sizeof(struct bc_disk));		bd->bd_number = j;		bd++;	}	}/*-----------------------------------------------------------*/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);	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--;		}	}		if (bc_pid_next) {		bc_pid_timer.expires = jiffies + 5 * HZ;		add_timer(&bc_pid_timer);	}	up(&bc_pid_sema);}/*-----------------------------------------------------------*/static void grab_requests();static void bc_request();static void do_bc_request() {#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,32))#define BC_NULL NULL#else#define BC_NULL#endif	if (NULL == CURRENT)		return;	grab_requests();	save_request_fn(BC_NULL);	bc_request(BC_NULL);#undef BC_NULL}static void grab_requests(){	register struct request *prev, *tail, *curr;		if (NULL == (curr = CURRENT))		return;	if (NULL != (tail = BC_CURRENT))		while (tail->next)			tail = tail->next;	prev = NULL;	while (curr) {		if (get_bcdev(curr->rq_dev)) {			if (tail) tail->next = curr;			else      BC_CURRENT = curr;			if (prev) prev->next = curr->next;			else      CURRENT    = curr->next; 			tail = curr;		} else {			if (prev) prev = prev->next;			else      prev = CURRENT; 		}		curr = curr->next;	}	if (tail) tail->next = NULL;}#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,32))static void bc_request(request_queue_t *abcd)#elsestatic void bc_request()#endif{	struct bc_device	*bc;	struct bc_disk		*bd;	struct request		*req;	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			uptodate, i;repeat:	if (!BC_CURRENT) return;	req = BC_CURRENT;	BC_CURRENT = req->next;	uptodate = 0;	bc = get_bcdev(req->rq_dev);	bd = get_bcdsk(req->rq_dev);	if (!bc || !bd || !bc->bc_dentry || !bc->bc_dentry->d_inode) {		goto error_out;	}	if (!bd->bd_flags.configured) {		if (bc->bc_flags.busy) {			bd->bd_offset = bc->bc_offset +			(((loff_t)bc_gendisk.part[bd->bd_number].start_sect)<<9);		} else {			printk(KERN_ERR "bc: device not configured yet.\n");			goto error_out;		}	}	if (WRITE == req->cmd) {		if (bc->bc_flags.readonly) {			goto error_out;		}	} else if (READ != req->cmd) {		printk(KERN_ERR "bc: unknown command (%d).", req->cmd);		goto error_out;	}	sec   = (loff_t)req->sector + bc->bc_start_sector;	pos   = sec * 512 + bd->bd_offset;	len   = req->current_nr_sectors << 9;	dst   = req->buffer;	file  = bc->bc_file;	iv[0] = iv[1] = iv[2] = iv[3] = sec & 0xFFFF;	iv64  = sec+1;	bc->bc_activity = 1;		if (READ == req->cmd) {		fs = get_fs();		set_fs(KERNEL_DS);		spin_unlock_irq(&io_request_lock);		ret = file->f_op->read(file, dst, len, &pos);		spin_lock_irq(&io_request_lock);		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 {		for (i = 0; i < BC_BUFFERS; i++) {			if (atomic_dec_and_test(&bc_buffers[i].count)) {				buf = bc_buffers[i].ptr;				break;			} else				atomic_inc(&bc_buffers[i].count);		}		if (BC_BUFFERS == i) {			printk(KERN_ERR "bc: insufficient resources\n");			goto error_out;		}		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);			spin_unlock_irq(&io_request_lock);			ret = file->f_op->write(file, buf, size, &pos);			spin_lock_irq(&io_request_lock);			set_fs(fs);			if (ret != size) {				printk(KERN_ERR "bc: write error wanted %ld, wrote %ld\n", 					(unsigned long)size, (unsigned long)ret);				atomic_inc(&bc_buffers[i].count);				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;

⌨️ 快捷键说明

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