Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2018
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.57 KB | None | 0 0
  1. #include <linux/init.h> // Macros used to mark up functions e.g. __init __exit
  2. #include <linux/module.h> // Core header for loading LKMs into the kernel
  3. #include <linux/device.h> // Header to support the kernel Driver Model
  4. #include <linux/kernel.h> // Contains types, macros, functions for the kernel
  5. #include <linux/fs.h> // Header for the Linux file system support
  6. #include <asm/uaccess.h> // Required for the copy to user function
  7.  
  8. #include <crypto/skcipher.h>
  9. #include <linux/scatterlist.h>
  10. #include <crypto/hash.h>
  11. #include <crypto/sha.h>
  12.  
  13. #define DEVICE_NAME "crypto" ///< The device will appear at /dev/crypto using this value
  14. #define CLASS_NAME "cipher" ///< The device class -- this is a character device driver
  15.  
  16. MODULE_LICENSE("GPL");
  17. MODULE_AUTHOR("Marcelo Aquino, Jefferson Aparecido");
  18. MODULE_DESCRIPTION("A crypto Linux char driver"); ///< The description -- see modinfo
  19. MODULE_VERSION("0.1"); // A version number to inform users
  20.  
  21. struct tcrypt_result {
  22. struct completion completion;
  23. int res;
  24. };
  25.  
  26. /* tie all data structures together */
  27. struct skcipher_def {
  28. struct crypto_skcipher *tfm;
  29. struct skcipher_request *req;
  30. struct tcrypt_result result;
  31. };
  32.  
  33. // Module parameters
  34. static char *key = NULL;
  35. module_param(key, charp, 0000);
  36. MODULE_PARM_DESC(key, "Chave simetrica para cifra e decifrar os dados");
  37.  
  38. static int majorNumber; ///< Stores the device number -- determined automatically
  39. static char buffer[1024] = {0}; ///< Memory for the string that is passed from userspace
  40. static short buffer_size; ///< Used to remember the size of the string stored
  41. static int numberOpens = 0; ///< Counts the number of times the device is opened
  42. static struct class* ebbcharClass = NULL; ///< The device-driver class struct pointer
  43. static struct device* ebbcharDevice = NULL; ///< The device-driver device struct pointer
  44.  
  45. // The prototype functions for the character driver -- must come before the struct definition
  46. static int dev_open(struct inode *, struct file *);
  47. static int dev_release(struct inode *, struct file *);
  48. static ssize_t dev_read(struct file *, char *, size_t, loff_t *);
  49. static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);
  50.  
  51. // Crypto
  52. static struct skcipher_def sk;
  53. static struct crypto_shash *hashalg;
  54.  
  55. /** @brief Devices are represented as file structure in the kernel. The file_operations structure from
  56. * /linux/fs.h lists the callback functions that you wish to associated with your file operations
  57. * using a C99 syntax structure. char devices usually implement open, read, write and release calls
  58. */
  59. static struct file_operations fops =
  60. {
  61. .open = dev_open,
  62. .read = dev_read,
  63. .write = dev_write,
  64. .release = dev_release,
  65. };
  66.  
  67. struct sdesc {
  68. struct shash_desc shash;
  69. char ctx[];
  70. };
  71.  
  72. /* Callback function */
  73. static void test_skcipher_cb(struct crypto_async_request *req, int rc)
  74. {
  75. struct tcrypt_result *result = req->data;
  76.  
  77. if (rc == -EINPROGRESS) {
  78. #ifdef CRYPTO_DEBUG
  79. printk(KERN_INFO "crypto: failed\n");
  80. #endif
  81. return;
  82. }
  83.  
  84. result->res = rc;
  85. complete(&result->completion);
  86.  
  87. pr_info("Encryption finished successfully\n");
  88. }
  89.  
  90. /** @brief The LKM initialization function
  91. * The static keyword restricts the visibility of the function to within this C file. The __init
  92. * macro means that for a built-in driver (not a LKM) the function is only used at initialization
  93. * time and that it can be discarded and its memory freed up after that point.
  94. * @return returns 0 if successful
  95. */
  96. static int __init crypto_init(void)
  97. {
  98. int ret;
  99.  
  100. printk(KERN_INFO "crypto: Initializing the crypto device\n");
  101.  
  102. if (key == NULL) {
  103. printk(KERN_ERR "crypto: You must supply the AES key to the module.\n");
  104. return -1;
  105. } else if (strlen(key) != 32) {
  106. printk(KERN_ERR "crypto: You must supply an AES with size of 32.\n");
  107. return -1;
  108. } else {
  109. printk(KERN_INFO "crypto: AES key set to: %s\n", key);
  110. }
  111.  
  112. sk.tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
  113. if (IS_ERR(sk.tfm)) {
  114. printk(KERN_ERR "crypto: could not allocate skcipher handle\n");
  115. return PTR_ERR(sk.tfm);
  116. }
  117.  
  118. sk.req = skcipher_request_alloc(sk.tfm, GFP_KERNEL);
  119. if (!sk.req) {
  120. printk(KERN_ERR "crypto: could not allocate skcipher request\n");
  121. return -ENOMEM;
  122. }
  123.  
  124. skcipher_request_set_callback(sk.req, CRYPTO_TFM_REQ_MAY_BACKLOG,
  125. test_skcipher_cb, &sk.result);
  126.  
  127. if (crypto_skcipher_setkey(sk.tfm, key, 32)) {
  128. printk(KERN_ERR "crypto: aes key could not be set\n");
  129. crypto_free_skcipher(sk.tfm);
  130. return -EAGAIN;
  131. }
  132.  
  133. hashalg = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC);
  134. if (IS_ERR(hashalg)) {
  135. pr_info("crypto: could not allocate crypto sha1\n");
  136. ret = PTR_ERR(hashalg);
  137. goto hashalg_fail;
  138. }
  139.  
  140. // Try to dynamically allocate a major number for the device -- more difficult but worth it
  141. majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
  142. if (majorNumber<0){
  143. printk(KERN_ALERT "crypto failed to register a major number\n");
  144. ret = majorNumber;
  145. goto device_register_fail;
  146. }
  147. printk(KERN_INFO "crypto: registered correctly with major number %d\n", majorNumber);
  148.  
  149. // Register the device class
  150. ebbcharClass = class_create(THIS_MODULE, CLASS_NAME);
  151. if (IS_ERR(ebbcharClass)){ // Check for error and clean up if there is
  152. unregister_chrdev(majorNumber, DEVICE_NAME);
  153. printk(KERN_ALERT "Failed to register device class\n");
  154. return PTR_ERR(ebbcharClass); // Correct way to return an error on a pointer
  155. }
  156. printk(KERN_INFO "crypto: device class registered correctly\n");
  157.  
  158. // Register the device driver
  159. ebbcharDevice = device_create(ebbcharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
  160. if (IS_ERR(ebbcharDevice)){ // Clean up if there is an error
  161. class_destroy(ebbcharClass); // Repeated code but the alternative is goto statements
  162. unregister_chrdev(majorNumber, DEVICE_NAME);
  163. printk(KERN_ALERT "Failed to create the device\n");
  164. return PTR_ERR(ebbcharDevice);
  165. }
  166. printk(KERN_INFO "crypto: device class created correctly\n"); // Made it! device was initialized
  167.  
  168. return 0;
  169.  
  170. hashalg_fail:
  171. crypto_free_skcipher(sk.tfm);
  172. return ret;
  173. device_register_fail:
  174. crypto_free_shash(hashalg);
  175. return ret;
  176. }
  177.  
  178. /** @brief The LKM cleanup function
  179. * Similar to the initialization function, it is static. The __exit macro notifies that if this
  180. * code is used for a built-in driver (not a LKM) that this function is not required.
  181. */
  182. static void __exit crypto_exit(void)
  183. {
  184. if (sk.tfm != NULL) {
  185. crypto_free_skcipher(sk.tfm);
  186. }
  187. if (sk.req != NULL) {
  188. skcipher_request_free(sk.req);
  189. }
  190.  
  191. device_destroy(ebbcharClass, MKDEV(majorNumber, 0)); // remove the device
  192. class_unregister(ebbcharClass); // unregister the device class
  193. class_destroy(ebbcharClass); // remove the device class
  194. unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number
  195. printk(KERN_INFO "crypto: Goodbye from the crypto module\n");
  196. }
  197.  
  198. /** @brief The device open function that is called each time the device is opened
  199. * This will only increment the numberOpens counter in this case.
  200. * @param inodep A pointer to an inode object (defined in linux/fs.h)
  201. * @param filep A pointer to a file object (defined in linux/fs.h)
  202. */
  203. static int dev_open(struct inode *inodep, struct file *filep)
  204. {
  205. numberOpens++;
  206. printk(KERN_INFO "crypto: Device has been opened %d time(s)\n", numberOpens);
  207.  
  208. return 0;
  209. }
  210.  
  211. /** @brief This function is called whenever device is being read from user space i.e. data is
  212. * being sent from the device to the user. In this case is uses the copy_to_user() function to
  213. * send the buffer string to the user and captures any errors.
  214. * @param filep A pointer to a file object (defined in linux/fs.h)
  215. * @param buffer The pointer to the buffer to which this function writes the data
  216. * @param len The length of the b
  217. * @param offset The offset if required
  218. */
  219. static ssize_t dev_read(struct file *filep, char *ubuf, size_t len, loff_t *offset)
  220. {
  221. int error_count = 0;
  222. // copy_to_user has the format ( * to, *from, size) and returns 0 on success
  223. error_count = copy_to_user(ubuf, buffer, buffer_size);
  224.  
  225. if (error_count==0) { // if true then have success
  226. #ifdef CRYPTO_DEBUG
  227. printk(KERN_INFO "crypto: Sent %d characters to the user\n", buffer_size);
  228. #endif
  229. return buffer_size;
  230. } else {
  231. printk(KERN_INFO "crypto: Failed to send %d characters to the user\n", error_count);
  232. return -EFAULT; // Failed -- return a bad address buffer (i.e. -14)
  233. }
  234. }
  235.  
  236. /** @brief Encrypt or decrypt a string
  237. * @param op Operation, 0 being encrypt and 1 decrypt
  238. * @param src The source string
  239. * @param dst The destination string
  240. * @param len The length of the source string
  241. */
  242. static int crypto_func(uint8_t op, const char *src, char *dst, int len)
  243. {
  244. char source[16];
  245. char derived[16];
  246. int i, rc, blocks, bytes = 0;
  247. #ifdef CRYPTO_DEBUG
  248. int j;
  249. #endif
  250. struct scatterlist src_sg, dst_sg;
  251.  
  252. if (len == 0 || len % 16) {
  253. #ifdef CRYPTO_DEBUG
  254. printk(KERN_INFO "crypto: invalid string size\n");
  255. #endif
  256. return 0;
  257. }
  258.  
  259. blocks = len / 16;
  260.  
  261. sg_init_one(&src_sg, source, 16);
  262. sg_init_one(&dst_sg, derived, 16);
  263. skcipher_request_set_crypt(sk.req, &src_sg, &dst_sg, 16, NULL);
  264.  
  265. for (i = 0; i < blocks; ++i) {
  266. (void)memcpy((void *)source, (void *)&src[bytes], 16);
  267.  
  268. if (op == 0) {
  269. #ifdef CRYPTO_DEBUG
  270. printk(KERN_INFO "crypto: encrypting block: %d\n", i);
  271. printk(KERN_INFO "crypto: source hex: ");
  272. for (j = 0; j < 16; ++j) {
  273. printk(KERN_CONT "0x%02X ", source[j] & 0xff);
  274. }
  275. #endif
  276.  
  277. rc = crypto_skcipher_encrypt(sk.req);
  278. } else {
  279. #ifdef CRYPTO_DEBUG
  280. printk(KERN_INFO "crypto: decrypting block: %d\n", i);
  281. printk(KERN_INFO "crypto: source hex: ");
  282. for (j = 0; j < 16; ++j) {
  283. printk(KERN_CONT "0x%02X ", source[j] & 0xff);
  284. }
  285. #endif
  286. rc = crypto_skcipher_decrypt(sk.req);
  287. }
  288.  
  289. if (rc == -EINPROGRESS || rc == -EBUSY) {
  290. wait_for_completion(&sk.result.completion);
  291. rc = sk.result.res;
  292. }
  293.  
  294. #ifdef CRYPTO_DEBUG
  295. printk(KERN_INFO "crypto: derived hex: ");
  296. for (j = 0; j < 16; ++j) {
  297. printk(KERN_CONT "0x%02X ", derived[j] & 0xff);
  298. }
  299. #endif
  300. (void)memcpy((void *)&dst[bytes], (void *)derived, 16);
  301. bytes += 16;
  302. }
  303.  
  304. return bytes;
  305. }
  306.  
  307. uint8_t h2i(char c)
  308. {
  309. uint8_t i = 0;
  310. if (c <= '9') {
  311. i += c - '0';
  312. } else if (c >= 'a') {
  313. i += c - 'a' + 10;
  314. } else {
  315. i += c - 'A' + 10;
  316. }
  317. return i;
  318. }
  319.  
  320. char i2h(uint8_t i)
  321. {
  322. uint8_t k = i & 0x0F;
  323. if (k <= 9) {
  324. return '0' + k;
  325. } else {
  326. return 'a' + k - 10;
  327. }
  328. }
  329.  
  330. static struct sdesc *init_sdesc(struct crypto_shash *alg)
  331. {
  332. struct sdesc *sdesc;
  333. int size;
  334.  
  335. size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
  336. sdesc = kmalloc(size, GFP_KERNEL);
  337. if (!sdesc) {
  338. return ERR_PTR(-ENOMEM);
  339. }
  340. sdesc->shash.tfm = alg;
  341. sdesc->shash.flags = 0x0;
  342. return sdesc;
  343. }
  344.  
  345. static int TSS_sha1(const unsigned char *data, unsigned int datalen,
  346. unsigned char *digest)
  347. {
  348. struct sdesc *sdesc;
  349. int ret;
  350.  
  351. sdesc = init_sdesc(hashalg);
  352. if (IS_ERR(sdesc)) {
  353. pr_info("trusted_key: can't alloc sha1\n");
  354. return PTR_ERR(sdesc);
  355. }
  356.  
  357. ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
  358. kfree(sdesc);
  359. return ret;
  360. }
  361.  
  362. /** @brief This function is called whenever the device is being written to from user space i.e.
  363. * data is sent to the device from the user. The data is copied to the buffer[] array in this
  364. * LKM using the sprintf() function along with the length of the string.
  365. * @param filep A pointer to a file object
  366. * @param buffer The buffer to that contains the string to write to the device
  367. * @param len The length of the array of data that is being passed in the const char buffer
  368. * @param offset The offset if required
  369. */
  370. static ssize_t dev_write(struct file *filep, const char *ubuf, size_t len, loff_t *offset)
  371. {
  372. int i, rc = 0;
  373. uint8_t padding, val;
  374. char *str;
  375. const uint8_t zero = 0;
  376. unsigned char digest[SHA1_DIGEST_SIZE] = {0};
  377.  
  378. if (len < 2) {
  379. return -1;
  380. }
  381. #ifdef CRYPTO_DEBUG
  382. printk(KERN_INFO "crypto: write: ubuf: '%.*s' - len: %zu\n", (int)len, ubuf, len);
  383. #endif
  384. len = len - 2;
  385. if (!len) {
  386. return 0;
  387. }
  388.  
  389. if (ubuf[0] == 'c' && ubuf[1] == ' ') {
  390. buffer_size = 0;
  391.  
  392. (void)memcpy((void *)buffer, (void *)&ubuf[2], len);
  393.  
  394. padding = (16 - len % 16) % 16;
  395. if (padding) {
  396. for (i = len; i < len + padding; ++i) {
  397. (void)memcpy((void *)&buffer[i], &zero, 1);
  398. }
  399. len = len + padding;
  400. }
  401. rc = crypto_func(0, buffer, buffer, len);
  402. if (rc > 0) {
  403. str = &buffer[(len - 1) * 2];
  404. for (i = len - 1; i >= 0; --i) {
  405. val = buffer[i];
  406. buffer[i * 2] = i2h(val >> 4);
  407. buffer[(i * 2) + 1] = i2h(val);
  408. }
  409. buffer_size = len * 2;
  410. #ifdef CRYPTO_DEBUG
  411. printk(KERN_INFO "crypto: buffer - size: %d - value: %.*s", buffer_size, buffer_size, buffer);
  412. #endif
  413. }
  414. } else if (ubuf[0] == 'd' && ubuf[1] == ' ') {
  415. if (len % (16*2)) {
  416. return -1;
  417. }
  418. str = buffer;
  419. for (i = 2; i <= len; str++) {
  420. val = h2i(ubuf[i++]) << 4;
  421. val += h2i(ubuf[i++]);
  422. *str = val;
  423. }
  424. rc = crypto_func(1, buffer, buffer, len/2);
  425. if (rc > 0) {
  426. buffer_size = rc;
  427. printk(KERN_INFO "crypto: buffer - size: %d - value: %.*s", buffer_size, buffer_size, buffer);
  428. } else {
  429. buffer_size = 0;
  430. }
  431. } else if (ubuf[0] == 'h' && ubuf[1] == ' ') {
  432. buffer_size = 0;
  433. rc = TSS_sha1(&ubuf[2], len, digest);
  434. if (rc < 0) {
  435. #ifdef CRYPTO_DEBUG
  436. printk(KERN_INFO "crypto: sha1 failed\n");
  437. #endif
  438. } else {
  439. for (i = 0; i < SHA1_DIGEST_SIZE; ++i) {
  440. val = digest[i];
  441. buffer[i * 2] = i2h(val >> 4);
  442. buffer[(i * 2) + 1] = i2h(val);
  443. }
  444. buffer_size = SHA1_DIGEST_SIZE * 2;
  445. }
  446. }
  447.  
  448. return rc;
  449. }
  450.  
  451. /** @brief The device release function that is called whenever the device is closed/released by
  452. * the userspace program
  453. * @param inodep A pointer to an inode object (defined in linux/fs.h)
  454. * @param filep A pointer to a file object (defined in linux/fs.h)
  455. */
  456. static int dev_release(struct inode *inodep, struct file *filep)
  457. {
  458. #ifdef CRYPTO_DEBUG
  459. printk(KERN_INFO "crypto: Device successfully closed\n");
  460. #endif
  461.  
  462. return 0;
  463. }
  464.  
  465. /** @brief A module must use the module_init() module_exit() macros from linux/init.h, which
  466. * identify the initialization function at insertion time and the cleanup function (as
  467. * listed above)
  468. */
  469. module_init(crypto_init);
  470. module_exit(crypto_exit);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement