· 5 years ago · Jan 23, 2020, 06:38 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
141/* Parse buffer if user chose to encrypt data. */
142static int parse_buf_enc(char buffer[]){
143
144
145
146
147
148
149
150
151}
152
153static int xor_data(void){
154
155 int i;
156 unsigned char temp = 0;
157
158 /* Generate element from secret/private key
159 * and public key
160 */
161 generate_element(s_key, p_key);
162 printk(KERN_INFO "Element for encrypt/decrypt: %s %d\n", element, strlen(element));
163
164 for(i = 0; i < strlen(buffer); i++){
165
166 if((buffer[i] == '\n') || (buffer[i] == '\0')) break;
167
168 temp = buffer[i];
169 temp ^= element[i % ELEMENT_LEN];
170 if(temp < 32) temp ^= element[i % ELEMENT_LEN];
171 buffer[i] = temp;
172 }
173
174 printk(KERN_INFO "Result of xor: %s\n", buffer);
175 return SUCCESS;
176}
177
178static int generate_end_buffer(void){
179 char temp[BUF_LEN];
180 int i;
181
182 memset(temp, '\0', BUF_LEN);
183 strcpy(temp, buffer);
184 memset(buffer, '\0', BUF_LEN);
185
186 if(option == 1){
187 buffer[0] = p_key;
188 buffer[1] = '|';
189 strcat(buffer, temp);
190 }else if(option == 2){
191 for(i = 0; i < strlen(temp); i++) buffer[i] = temp[i];}
192 else{
193 printk(KERN_INFO "Oops! Something went wrong.\n");
194 return -1;
195 }
196
197 //buffer[strlen(buffer)] = '\0';
198 printk(KERN_INFO "Buffer after xor: %s\n", buffer);
199 return SUCCESS;
200}
201
202/*
203 * Initialization:
204 * 1. Register device driver
205 * 2. Allocate buffer
206 * 3. Initialize buffer
207 * 4. Generate secret key
208 */
209int encrypt_init(void) {
210
211 int result;
212
213 /* Registering device. */
214 major = register_chrdev(0, DEVICE_NAME, &encrypt_fops);
215 if(major < 0) {
216 printk(KERN_INFO "encrypt: cannot obtain major number %d\n", major);
217 return major;
218 }
219
220 printk(KERN_INFO "encrypt assigned to major number: %d\n", major);
221 /* Allocating memory for the buffer. */
222 buff_ptr = kmalloc(BUF_LEN, GFP_KERNEL);
223 if(!buff_ptr) {
224 result = -ENOMEM;
225 goto fail;
226 }
227
228 memset(buffer, 0, BUF_LEN);
229 printk(KERN_INFO "Inserting encrypt module\n");
230 printk(KERN_INFO "Seed for generating secret key: %d\n", seed);
231
232 secret_key = prng(seed);
233 printk(KERN_INFO "Secret key: %d\n", secret_key);
234
235 return 0;
236
237fail:
238 encrypt_exit();
239 return result;
240
241}
242
243/*
244 * Cleanup:
245 * 1. Unregister device driver
246 * 2. Free buffer
247 */
248void encrypt_exit(void) {
249
250 /* Freeing the major number. */
251 unregister_chrdev(major, DEVICE_NAME);
252
253 /* Freeing buffer memory. */
254 /* If used kfree(buff) causes stack overflow and (core dumped)?*/
255 //if(buff_ptr) kfree(buff_ptr);
256
257 printk(KERN_INFO "Removing encrypt module\n");
258
259}
260
261/* File open function. */
262static int encrypt_open(struct inode *inode, struct file *filp)
263{
264
265 if(Device_Open) return -EBUSY;
266
267 Device_Open++;
268 sprintf(buffer, "Device opened.\nSecret key: %d\n", secret_key);
269 buff_ptr = buffer;
270 try_module_get(THIS_MODULE);
271
272 return SUCCESS;
273}
274
275/* File close function. */
276static int encrypt_release(struct inode *inode, struct file *filp)
277{
278 Device_Open--; /* We're now ready for our next caller. */
279
280 /*
281 * Decrement the usage count, or else once you opened the file, you'll
282 * never get get rid of the module.
283 */
284 module_put(THIS_MODULE);
285
286 return 0;
287}
288
289/*
290 * File read function
291 * Parameters:
292 * filp - a type file structure;
293 * buf - a buffer, from which the user space function (fread) will read;
294 * len - a counter with the number of bytes to transfer, which has the same
295 * value as the usual counter in the user space function (fread);
296 * f_pos - a position of where to start reading the file;
297 * Operation:
298 * The encrypt_read function transfers data from the driver buffer (buffer)
299 * to user space with the function copy_to_user.
300 */
301static ssize_t encrypt_read(struct file *filp, char *buf, size_t len, loff_t *f_pos)
302{
303 /* Size of valid data in memory - data to send in user space. */
304 int data_size = 0;
305
306 /* Processing data and generating end buffer for sending
307 * to user space
308 */
309
310 xor_data();
311 generate_end_buffer();
312
313 if (*f_pos == 0) {
314 /* Get size of valid data. */
315 data_size = strlen(buff_ptr);
316
317 /* Send data to user space. */
318 if (copy_to_user(buf, buff_ptr, data_size) != 0) {
319 return -EFAULT;
320 }
321 else{
322 (*f_pos) += data_size;
323 return data_size;
324 }
325 }
326 else return 0;
327}
328
329/*
330 * File write function
331 * Parameters:
332 * filp - a type file structure;
333 * buf - a buffer in which the user space function (fwrite) will write;
334 * len - a counter with the number of bytes to transfer, which has the same
335 * values as the usual counter in the user space function (fwrite);
336 * f_pos - a position of where to start writing in the file;
337 * Operation:
338 * The function copy_from_user transfers the data from user space to kernel space.
339 */
340static ssize_t encrypt_write(struct file *filp, const char *buf, size_t len, loff_t *f_pos)
341{
342 /* Reset memory. */
343 memset(buff_ptr, 0, BUF_LEN);
344
345 /* Get data from user space.*/
346 if (copy_from_user(buff_ptr, buf, len) != 0)
347 {
348 return -EFAULT;
349 }
350 else
351 {
352 strcpy(buffer, buf);
353 if(buffer[0] == '1'){
354 parse_buf_enc(buffer);
355 }else if(buffer[0] == '2'){
356 parse_buf_dec(buff);
357 }else{
358 return -1;
359 }
360
361 return len;
362 }
363
364}