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

📄 dm-target.c

📁 源码开放的加密软件。最新版本!!可以在一个文件内部创建多样化的加密磁盘并且将其配置为一个可以通过一个驱动器盘符访问的虚拟磁盘.任何存储在该虚拟磁盘上的文件可以被自动地实时加密,并且只有当使用正确的密码
💻 C
📖 第 1 页 / 共 2 页
字号:
	mempool_destroy (tc->bio_ctx_pool);	mempool_destroy (tc->pg_pool);	crypto_close (tc->ci);	kfree(tc->volume_path);	dm_put_device(ti, tc->dev);	kfree(tc);}// Checks if two regions overlap (borders are parts of regions)static int RegionsOverlap (u64 start1, u64 end1, u64 start2, u64 end2){	return (start1 < start2) ? (end1 >= start2) : (start1 <= end2);}static void dereference_bio_ctx (struct bio_ctx *bc){	struct target_ctx *tc = (struct target_ctx *) bc->target->private;	if (!atomic_dec_and_test (&bc->ref_count))		return;	bio_endio (bc->orig_bio, bc->orig_bio->bi_size, bc->error);	mempool_free (bc, tc->bio_ctx_pool);}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)static void work_process (struct work_struct *qdata){	struct bio_ctx *bc = container_of(qdata, struct bio_ctx, work);#elsestatic void work_process (void *qdata){	struct bio_ctx *bc = (struct bio_ctx *) qdata;#endif	struct target_ctx *tc = (struct target_ctx *) bc->target->private;	struct bio_vec *bv;	u64 sec_no = bc->crypto_sector;	int seg_no;	unsigned long flags;	// Decrypt queued data	bio_for_each_segment (bv, bc->orig_bio, seg_no)	{		unsigned int secs = bv->bv_len / SECTOR_SIZE;		char *data = bvec_kmap_irq (bv, &flags);		DecryptSectors ((unsigned __int32 *)data, sec_no, secs, tc->ci);		sec_no += secs;		flush_dcache_page (bv->bv_page);		bvec_kunmap_irq (data, &flags);		if (seg_no + 1 < bc->orig_bio->bi_vcnt)			cond_resched ();	}	dereference_bio_ctx (bc);}static int truecrypt_endio (struct bio *bio, unsigned int bytes_done, int error){	struct bio_ctx *bc = (struct bio_ctx *) bio->bi_private;	struct target_ctx *tc = (struct target_ctx *) bc->target->private;	struct bio_vec *bv;	int seg_no;		trace (1, "end: sc=%llu fl=%ld rw=%ld sz=%d ix=%hd vc=%hd dn=%d er=%d\n",		(unsigned long long) bio->bi_sector, bio->bi_flags, bio->bi_rw, bio->bi_size, bio->bi_idx, bio->bi_vcnt, bytes_done, error);	if (error != 0)		bc->error = error;	if (bio->bi_size)	{		trace (2, "Outstanding IO: %d\n", bio->bi_size);		return 1;	}	if (bio_data_dir (bio) == READ)	{		bio_put (bio);		// Queue decryption to leave completion interrupt ASAP#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)		INIT_WORK (&bc->work, work_process);#else		INIT_WORK (&bc->work, work_process, bc);#endif		queue_work (work_queue, &bc->work);		return error;	}	// Free pages allocated for encryption	bio_for_each_segment (bv, bio, seg_no)	{		mempool_free (bv->bv_page, tc->pg_pool);  	}	bio_put (bio);	dereference_bio_ctx (bc);	return error;}static int truecrypt_map (struct dm_target *ti, struct bio *bio, union map_info *map_context){	struct target_ctx *tc = (struct target_ctx *) ti->private;	struct bio_ctx *bc;	struct bio *bion;	struct bio_vec *bv;	int seg_no;	trace (1, "map: sc=%llu fl=%ld rw=%ld sz=%d ix=%hd vc=%hd\n",		(unsigned long long) bio->bi_sector, bio->bi_flags, bio->bi_rw, bio->bi_size, bio->bi_idx, bio->bi_vcnt);	// Write protection	if (bio_data_dir (bio) == WRITE && READ_ONLY (tc))		return -EPERM;	// Validate segment sizes	bio_for_each_segment (bv, bio, seg_no)	{		if (bv->bv_len & (SECTOR_SIZE - 1))		{			error ("unsupported bio segment size %d (%ld %d %hd %hd)\n",				bv->bv_len, bio->bi_rw, bio->bi_size, bio->bi_idx, bio->bi_vcnt);			return -EINVAL;		}	}	// Bio context	bc = malloc_wait (tc->bio_ctx_pool, bio_data_dir (bio));	if (!bc)	{		error ("bio context allocation failed\n");		return -ENOMEM;	}	atomic_set (&bc->ref_count, 1);	bc->orig_bio = bio;	bc->error = 0;	bc->target = ti;	bc->crypto_sector = tc->start + (bio->bi_sector - ti->begin);	// New bio for encrypted device	while (!(bion = bio_alloc (GFP_NOIO | __GFP_NOMEMALLOC, bio_segments (bio))))	{		congestion_wait (bio_data_dir (bio), HZ / 50);	}	bion->bi_bdev = tc->dev->bdev;	bion->bi_end_io = truecrypt_endio;	bion->bi_idx = 0;	bion->bi_private = bc;	bion->bi_rw = bio->bi_rw;	bion->bi_sector = bc->crypto_sector;	bion->bi_size = bio->bi_size;	bion->bi_vcnt = bio_segments (bio);	if (bio_data_dir (bio) == READ)	{		// Buffers of originating bio can be used for decryption		memcpy (bion->bi_io_vec,			bio_iovec (bio),			bion->bi_vcnt * sizeof (struct bio_vec));	}	else	{		u64 sec_no = bc->crypto_sector;		int seg_no;		// Encrypt data to be written		unsigned long flags, copyFlags;		char *data, *copy;		memset (bion->bi_io_vec, 0, sizeof (struct bio_vec) * bion->bi_vcnt);		bio_for_each_segment (bv, bio, seg_no)		{			struct bio_vec *cbv = bio_iovec_idx (bion, seg_no);			unsigned int secs = bv->bv_len / SECTOR_SIZE;			// Hidden volume protection			if (!READ_ONLY (tc) && HID_VOL_PROT (tc)				&& RegionsOverlap (sec_no, sec_no + secs - 1, tc->read_only_start, tc->read_only_end))			{				tc->flags |= TC_READ_ONLY | TC_PROTECTION_ACTIVATED;			}			if (READ_ONLY (tc))			{				// Write not permitted				bio_for_each_segment (cbv, bion, seg_no)				{					if (cbv->bv_page != NULL)						mempool_free (cbv->bv_page, tc->pg_pool);  				}				bio_put (bion);				bc->error = READ_ONLY (tc) ? -EPERM : -ENOMEM;				dereference_bio_ctx (bc);				return 0;			}			cbv->bv_page = malloc_wait (tc->pg_pool, bio_data_dir (bion));			cbv->bv_offset = 0;			cbv->bv_len = bv->bv_len;			copy = bvec_kmap_irq (cbv, &copyFlags);			data = bvec_kmap_irq (bv, &flags);			memcpy (copy, data, bv->bv_len);			EncryptSectors ((unsigned __int32 *) copy, sec_no, secs, tc->ci);			sec_no += secs;			bvec_kunmap_irq (data, &flags);			bvec_kunmap_irq (copy, &copyFlags);			flush_dcache_page (bv->bv_page);			flush_dcache_page (cbv->bv_page);			if (seg_no + 1 < bio->bi_vcnt)				cond_resched();		}	}	atomic_inc (&bc->ref_count);	generic_make_request (bion);	dereference_bio_ctx (bc);	return 0;}static int truecrypt_status (struct dm_target *ti, status_type_t type, char *result, unsigned int maxlen){	struct target_ctx *tc = (struct target_ctx *) ti->private;	switch (type)	{	case STATUSTYPE_INFO:		result[0] = 0;		break;	case STATUSTYPE_TABLE:		{			char name[32];			format_dev_t (name, tc->dev->bdev->bd_dev);			snprintf (result, maxlen, "%d %d 0 0 %s %llu %llu %llu %llu %llu %llu %d %s",				tc->ci->ea,				tc->ci->mode,				name,				(unsigned long long) tc->start,				tc->read_only_start,				tc->read_only_end,				tc->uid,				tc->mtime,				tc->atime,				tc->flags,				tc->volume_path);		}		break;	}	return 0;}static struct target_type truecrypt_target = {	.name   = "truecrypt",	.version= {TC_VERSION_NUM1, TC_VERSION_NUM2, TC_VERSION_NUM3},	.module = THIS_MODULE,	.ctr    = truecrypt_ctr,	.dtr    = truecrypt_dtr,	.map    = truecrypt_map,	.status = truecrypt_status};int __init dm_truecrypt_init(void){	int r;	if (!AutoTestAlgorithms ())	{		error ("self-test of algorithms failed");		return -ERANGE;	}	work_queue = create_workqueue ("truecryptq");	if (!work_queue)	{		error ("create_workqueue failed");		goto err;	}	bio_ctx_cache = kmem_cache_create ("truecrypt-bioctx", sizeof (struct bio_ctx), 0, 0, NULL, NULL);	if (!bio_ctx_cache)	{		error ("kmem_cache_create failed");		goto err;	}	r = dm_register_target (&truecrypt_target);	if (r < 0)	{		error ("register failed %d", r);		goto err;	}	return r;err:	if (work_queue)		destroy_workqueue (work_queue);	if (bio_ctx_cache)		kmem_cache_destroy (bio_ctx_cache);	return -ENOMEM;}void __exit dm_truecrypt_exit(void){	int r;	r = dm_unregister_target (&truecrypt_target);	if (r < 0)		error ("unregister failed %d", r);	destroy_workqueue (work_queue);	kmem_cache_destroy (bio_ctx_cache);}module_init(dm_truecrypt_init);module_exit(dm_truecrypt_exit);module_param_named(trace, trace_level, int, 0);MODULE_AUTHOR("TrueCrypt Foundation");MODULE_DESCRIPTION("device-mapper target for encryption and decryption of TrueCrypt volumes");MODULE_PARM_DESC(trace, "Trace level");MODULE_LICENSE("GPL and additional rights");

⌨️ 快捷键说明

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