· 5 years ago · Jan 22, 2020, 03:04 PM
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/kernel.h>
4#include <linux/fs.h>
5#include <linux/errno.h>
6#include <linux/types.h>
7#include <linux/fcntl.h>
8#include <linux/proc_fs.h>
9#include <asm/uaccess.h>
10#include <linux/string.h>
11#include <linux/slab.h>
12#include <linux/random.h>
13#include <linux/uaccess.h>
14
15MODULE_LICENSE("GPL");
16
17#define DEVICE_NAME "encrypt"
18#define SUCCESS 0
19#define BUF_LEN 80
20#define ELEMENT_LEN 8
21
22// Declaration of encrypt.c functions
23void encrypt_exit(void);
24int encrypt_init(void);
25static int encrypt_open(struct inode *, struct file *);
26static int encrypt_release(struct inode *, struct file *);
27static ssize_t encrypt_read(struct file *, char *buf, size_t , loff_t *);
28static ssize_t encrypt_write(struct file *, const char *buf, size_t , loff_t *);
29
30/* Structure that declares the usual file access functions. */
31struct file_operations encrypt_fops =
32{
33 read : encrypt_read,
34 write : encrypt_write,
35 open : encrypt_open,
36 release : encrypt_release
37};
38
39// Declaration of the init and exit functions.
40module_init(encrypt_init);
41module_exit(encrypt_exit);
42
43// Global variables of the driver
44static int major;
45static int Device_Open = 0;
46static char buffer[BUF_LEN];
47char *buff_ptr;
48unsigned char secret_key = '1';
49// Seed parametet init
50static int seed = 1;
51static int p_seed = 1;
52/* Secret/private key */
53unsigned char s_key = '0';
54/* Public key */
55unsigned char p_key = '0';
56unsigned char **p_key_endptr;
57/* Unique key - generated from secret/private key and public key */
58char unsigned element[8];
59/* Option from user space */
60int option;
61
62module_param(seed, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
63MODULE_PARM_DESC(seed, "Seed for secret key.");
64
65
66static void generate_element(const int s_key, const int p_key){
67
68 int i;
69 for(i = 0; i < ELEMENT_LEN; i++){
70 element[i] = (141996333 * s_key) + (211219983 * p_key) + 262970333;
71 element[i] += i * 51512;
72 element[i] %= 126;
73
74 /* First 32 chars in ASCII are not symbols */
75 if(element[i] <= 32) element[i] += 33;
76 }
77 element[strlen(element)] = '\0';
78}
79
80/*
81 * Pseudorandom number generator
82 * Returns unsigned char
83 */
84static unsigned char prng(const int seed){
85
86 unsigned int retVal = 0;
87
88 retVal = (56984671 * seed) + 91563437;
89 retVal %= 126;
90
91 /* First 32 chars in ASCII are not symbols */
92 if(retVal <= 32) retVal += 33;
93 return retVal;
94}
95
96
97/* Parse buffer if user chose to encrypt data. */
98static int parse_buf_enc(char buffer[]){
99
100 char temp[BUF_LEN];
101 char **temp_end;
102 int i;
103 int j = 0;
104 int k = 0;
105
106 memset(temp, '\0', BUF_LEN);
107
108 /* Get option from buffer (ENCRYPT or DECRYPT) */
109 option = buffer[0] - '0';
110 printk(KERN_INFO "Option: %d", option);
111
112 /* Get seed from buffer for generating public key */
113 for(i = 2; i < strlen(buffer); i++){
114 if(buffer[i] == '|'){
115 j = i;
116 break;
117 }
118 temp[i - 2] = buffer[i];
119 }
120 p_seed = simple_strtol(temp, temp_end, 10);
121 printk(KERN_INFO "P_SEED: %d\n", p_seed);
122
123 /* Get data from buffer (for ENCRYPT or DECRYPT) */
124 memset(temp, '\0', BUF_LEN);
125 for(i = j + 1; i < strlen(buffer); i++, k++){
126 if(buffer[i] == '\0') break;
127 temp[k] = buffer[i];
128 }
129 temp[strlen(temp)] = '\0';
130 memset(buffer, '\0', BUF_LEN);
131 strcpy(buffer, temp);
132 printk(KERN_INFO "Data: %s\n", buffer);
133
134 /* Generate public key */
135 p_key = prng(p_seed);
136 printk(KERN_INFO "Public key: %d", p_key);
137
138 return SUCCESS;
139}
140
141static int xor_data(void){
142
143 int i;
144 unsigned char temp = 0;
145
146 /* Generate element from secret/private key
147 * and public key
148 */
149 generate_element(s_key, p_key);
150 printk(KERN_INFO "Element for encrypt/decrypt: %s %d\n", element, strlen(element));
151
152 for(i = 0; i < strlen(buffer); i++){
153
154 if((buffer[i] == '\n') || (buffer[i] == '\0')) break;
155
156 temp = buffer[i];
157 temp ^= element[i % ELEMENT_LEN];
158 if(temp < 32) temp ^= element[i % ELEMENT_LEN];
159 buffer[i] = temp;
160 }
161
162 printk(KERN_INFO "Result of xor: %s\n", buffer);
163 return SUCCESS;
164}
165
166static int generate_end_buffer(void){
167 char temp[BUF_LEN];
168 int i;
169
170 memset(temp, '\0', BUF_LEN);
171 strcpy(temp, buffer);
172 memset(buffer, '\0', BUF_LEN);
173
174 if(option == 1){
175 buffer[0] = p_key;
176 buffer[1] = '|';
177 strcat(buffer, temp);
178 }else if(option == 2){
179 for(i = 0; i < strlen(temp); i++) buffer[i] = temp[i];}
180 else{
181 printk(KERN_INFO "Oops! Something went wrong.\n");
182 return -1;
183 }
184
185 //buffer[strlen(buffer)] = '\0';
186 printk(KERN_INFO "Buffer after xor: %s\n", buffer);
187 return SUCCESS;
188}
189
190/*
191 * Initialization:
192 * 1. Register device driver
193 * 2. Allocate buffer
194 * 3. Initialize buffer
195 * 4. Generate secret key
196 */
197int encrypt_init(void) {
198
199 int result;
200
201 /* Registering device. */
202 major = register_chrdev(0, DEVICE_NAME, &encrypt_fops);
203 if(major < 0) {
204 printk(KERN_INFO "encrypt: cannot obtain major number %d\n", major);
205 return major;
206 }
207
208 printk(KERN_INFO "encrypt assigned to major number: %d\n", major);
209 /* Allocating memory for the buffer. */
210 buff_ptr = kmalloc(BUF_LEN, GFP_KERNEL);
211 if(!buff_ptr) {
212 result = -ENOMEM;
213 goto fail;
214 }
215
216 memset(buffer, 0, BUF_LEN);
217 printk(KERN_INFO "Inserting encrypt module\n");
218 printk(KERN_INFO "Seed for generating secret key: %d\n", seed);
219
220 secret_key = prng(seed);
221 printk(KERN_INFO "Secret key: %d\n", secret_key);
222
223 return 0;
224
225fail:
226 encrypt_exit();
227 return result;
228
229}
230
231/*
232 * Cleanup:
233 * 1. Unregister device driver
234 * 2. Free buffer
235 */
236void encrypt_exit(void) {
237
238 /* Freeing the major number. */
239 unregister_chrdev(major, DEVICE_NAME);
240
241 /* Freeing buffer memory. */
242 /* If used kfree(buff) causes stack overflow and (core dumped)?*/
243 //if(buff_ptr) kfree(buff_ptr);
244
245 printk(KERN_INFO "Removing encrypt module\n");
246
247}
248
249/* File open function. */
250static int encrypt_open(struct inode *inode, struct file *filp)
251{
252
253 if(Device_Open) return -EBUSY;
254
255 Device_Open++;
256 sprintf(buffer, "Device opened.\nSecret key: %d\n", secret_key);
257 buff_ptr = buffer;
258 try_module_get(THIS_MODULE);
259
260 return SUCCESS;
261}
262
263/* File close function. */
264static int encrypt_release(struct inode *inode, struct file *filp)
265{
266 Device_Open--; /* We're now ready for our next caller. */
267
268 /*
269 * Decrement the usage count, or else once you opened the file, you'll
270 * never get get rid of the module.
271 */
272 module_put(THIS_MODULE);
273
274 return 0;
275}
276
277/*
278 * File read function
279 * Parameters:
280 * filp - a type file structure;
281 * buf - a buffer, from which the user space function (fread) will read;
282 * len - a counter with the number of bytes to transfer, which has the same
283 * value as the usual counter in the user space function (fread);
284 * f_pos - a position of where to start reading the file;
285 * Operation:
286 * The encrypt_read function transfers data from the driver buffer (buffer)
287 * to user space with the function copy_to_user.
288 */
289static ssize_t encrypt_read(struct file *filp, char *buf, size_t len, loff_t *f_pos)
290{
291 /* Size of valid data in memory - data to send in user space. */
292 int data_size = 0;
293
294 xor_data();
295 generate_end_buffer();
296
297
298 if (*f_pos == 0) {
299 /* Get size of valid data. */
300 data_size = strlen(buff_ptr);
301
302 /* Send data to user space. */
303 if (copy_to_user(buf, buff_ptr, data_size) != 0) {
304 return -EFAULT;
305 }
306 else{
307 (*f_pos) += data_size;
308 return data_size;
309 }
310 }
311 else {
312 return 0;
313 }
314}
315
316/*
317 * File write function
318 * Parameters:
319 * filp - a type file structure;
320 * buf - a buffer in which the user space function (fwrite) will write;
321 * len - a counter with the number of bytes to transfer, which has the same
322 * values as the usual counter in the user space function (fwrite);
323 * f_pos - a position of where to start writing in the file;
324 * Operation:
325 * The function copy_from_user transfers the data from user space to kernel space.
326 */
327static ssize_t encrypt_write(struct file *filp, const char *buf, size_t len, loff_t *f_pos)
328{
329 /* Reset memory. */
330 memset(buff_ptr, 0, BUF_LEN);
331
332 /* Get data from user space.*/
333 if (copy_from_user(buff_ptr, buf, len) != 0)
334 {
335 return -EFAULT;
336 }
337 else
338 {
339 strcpy(buffer, buf);
340 if(buffer[0] == '1'){
341 parse_buf_enc(buffer);
342 }else if(buffer[0] == '2'){
343 //parse_buf_dec(buff);
344 }else{
345 return -1;
346 }
347
348 return len;
349 }
350
351}