Posted By

chriskennard on 05/17/16


Tagged


Versions (?)

C SDB


 / Published in: C
 

Problem code

  1. /*
  2.  * A sample, extra-simple block driver. Updated for kernel 2.6.31.
  3.  *
  4.  * (C) 2003 Eklektix, Inc.
  5.  * (C) 2010 Pat Patterson <pat at superpat dot com>
  6.  * Redistributable under the terms of the GNU GPL.
  7.  */
  8.  
  9. #include <linux/module.h>
  10. #include <linux/moduleparam.h>
  11. #include <linux/init.h>
  12.  
  13. #include <linux/kernel.h> /* printk() */
  14. #include <linux/fs.h> /* everything... */
  15. #include <linux/errno.h> /* error codes */
  16. #include <linux/types.h> /* size_t */
  17. #include <linux/vmalloc.h>
  18. #include <linux/genhd.h>
  19. #include <linux/blkdev.h>
  20. #include <linux/hdreg.h>
  21. #include <linux/crypto.h>
  22.  
  23. static char * cry_key = "thisismykey"; //setting up crypto
  24. struct crypto_cipher *crypt;
  25. static int crypto_key_len = 11;
  26. module_param(cry_key, charp, 0644);
  27.  
  28.  
  29. MODULE_LICENSE("Dual BSD/GPL");
  30. static char *Version = "1.4";
  31.  
  32. static int major_num = 0;
  33. module_param(major_num, int, 0);
  34. static int logical_block_size = 512;
  35. module_param(logical_block_size, int, 0);
  36. static int nsectors = 1024; /* How big the drive is */
  37. module_param(nsectors, int, 0);
  38.  
  39. /*
  40.  * We can tweak our hardware sector size, but the kernel talks to us
  41.  * in terms of small sectors, always.
  42.  */
  43. #define KERNEL_SECTOR_SIZE 512
  44.  
  45. /*
  46.  * Our request queue.
  47.  */
  48. static struct request_queue *Queue;
  49.  
  50. /*
  51.  * The internal representation of our device.
  52.  */
  53. static struct sbd_device {
  54. unsigned long size;
  55. spinlock_t lock;
  56. u8 *data;
  57. struct gendisk *gd;
  58. } Device;
  59.  
  60. /*
  61.  * Handle an I/O request.
  62.  */
  63. static void sbd_transfer(struct sbd_device *dev, sector_t sector, unsigned long nsect, char *buffer, int write) {
  64. crypto_cipher_setkey(crypt, cry_key, crypto_key_len);
  65. char *mode[2];
  66. unsigned long length;
  67. int i = 0;
  68. u8 *dst;
  69. u8 *src;
  70. unsigned long offset = sector * logical_block_size;
  71. unsigned long nbytes = nsect * logical_block_size;
  72.  
  73. if ((offset + nbytes) > dev->size) {
  74. printk (KERN_NOTICE "sbd: Beyond-end write (%ld %ld)\n", offset, nbytes);
  75. return;
  76. }
  77. if (write){
  78. mode[0] = "UNENCRYPTED";
  79. mode[1] = "ENCRYPTED";
  80. dst = dev->data + offset;
  81. src = buffer;
  82. for(i = 0; i < nbytes; i += crypto_cipher_blocksize(crypt)){
  83. crypto_cipher_encrypt_one(crypt, dst+i, src+i);
  84. }
  85. }
  86. else{
  87. mode[0] = "ENCRYPTED";
  88. mode[1] = "UNENCRYPTED";
  89. dst = buffer;
  90. src = dev->data + offset;
  91. for(i = 0; i < nbytes; i += crypto_cipher_blocksize(crypt)){
  92. crypto_cipher_decrypt_one(crypt, dst+i, src+i);
  93. }
  94. }
  95. /*length = nbytes;
  96. printk("%s:", mode[0]);
  97. while(length--){
  98. printk("%u", (unsigned) *src++);
  99. }
  100. length = nbytes;
  101. printk("%s:", mode[0]);
  102. while(length--){
  103. printk("%u", (unsigned) *dst++);
  104. }
  105. printk("----------------------------------------------\n");
  106. */
  107. }
  108.  
  109.  
  110. static void sbd_request(struct request_queue *q) {
  111. struct request *req;
  112.  
  113. req = blk_fetch_request(q);
  114. while (req != NULL) {
  115. // blk_fs_request() was removed in 2.6.36 - many thanks to
  116. // Christian Paro for the heads up and fix...
  117. //if (!blk_fs_request(req)) {
  118. if (req == NULL || (req->cmd_type != REQ_TYPE_FS)) {
  119. printk (KERN_NOTICE "Skip non-CMD request\n");
  120. __blk_end_request_all(req, -EIO);
  121. continue;
  122. }
  123. sbd_transfer(&Device, blk_rq_pos(req), blk_rq_cur_sectors(req),
  124. req->buffer, rq_data_dir(req));
  125. if ( ! __blk_end_request_cur(req, 0) ) {
  126. req = blk_fetch_request(q);
  127. }
  128. }
  129. }
  130.  
  131. /*
  132.  * The HDIO_GETGEO ioctl is handled in blkdev_ioctl(), which
  133.  * calls this. We need to implement getgeo, since we can't
  134.  * use tools such as fdisk to partition the drive otherwise.
  135.  */
  136. int sbd_getgeo(struct block_device * block_device, struct hd_geometry * geo) {
  137. long size;
  138.  
  139. /* We have no real geometry, of course, so make something up. */
  140. size = Device.size * (logical_block_size / KERNEL_SECTOR_SIZE);
  141. geo->cylinders = (size & ~0x3f) >> 6;
  142. geo->heads = 4;
  143. geo->sectors = 16;
  144. geo->start = 0;
  145. return 0;
  146. }
  147.  
  148. /*
  149.  * The device operations structure.
  150.  */
  151. static struct block_device_operations sbd_ops = {
  152. .owner = THIS_MODULE,
  153. .getgeo = sbd_getgeo
  154. };
  155.  
  156. static int __init sbd_init(void) {
  157. crypt = crypto_alloc_cipher("aes", 0, 0);
  158.  
  159. /*
  160. * Set up our internal device.
  161. */
  162. Device.size = nsectors * logical_block_size;
  163. spin_lock_init(&Device.lock);
  164. Device.data = vmalloc(Device.size);
  165. if (Device.data == NULL)
  166. return -ENOMEM;
  167. /*
  168. * Get a request queue.
  169. */
  170. Queue = blk_init_queue(sbd_request, &Device.lock);
  171. if (Queue == NULL)
  172. goto out;
  173. blk_queue_logical_block_size(Queue, logical_block_size);
  174. /*
  175. * Get registered.
  176. */
  177. major_num = register_blkdev(major_num, "sbd");
  178. if (major_num < 0) {
  179. printk(KERN_WARNING "sbd: unable to get major number\n");
  180. goto out;
  181. }
  182. /*
  183. * And the gendisk structure.
  184. */
  185. Device.gd = alloc_disk(16);
  186. if (!Device.gd)
  187. goto out_unregister;
  188. Device.gd->major = major_num;
  189. Device.gd->first_minor = 0;
  190. Device.gd->fops = &sbd_ops;
  191. Device.gd->private_data = &Device;
  192. strcpy(Device.gd->disk_name, "sbd0");
  193. set_capacity(Device.gd, nsectors);
  194. Device.gd->queue = Queue;
  195. add_disk(Device.gd);
  196.  
  197. return 0;
  198.  
  199. out_unregister:
  200. unregister_blkdev(major_num, "sbd");
  201. out:
  202. vfree(Device.data);
  203. return -ENOMEM;
  204. }
  205.  
  206. static void __exit sbd_exit(void){
  207. crypto_free_cipher(crypt);
  208. del_gendisk(Device.gd);
  209. put_disk(Device.gd);
  210. unregister_blkdev(major_num, "sbd");
  211. blk_cleanup_queue(Queue);
  212. vfree(Device.data);
  213. }
  214.  
  215. module_init(sbd_init);
  216. module_exit(sbd_exit);

Report this snippet  

You need to login to post a comment.