CSE 506 OPERATING SYSTEM SPRING 2019
					HOMEWORK ASSIGNMENT 1
					AKANKSHA MAAHAJAN
					112074564

PROBLEM STATEMENT:
Create a Linux kernel module (in vanilla 4.20.y Linux) that, when loaded into Linux, will support a new system call
called
	sys_cpenc(infile, outfile, keybuf, keylen, flags)
where "infile" is the name of an input file to encrypt or decrypt, "outfile" is the output file,
"keybuf" is a buffer holding the cipher key, "keylen" is the length of that buffer, and "flags" determine
if you're encrypting or decrypting.



=> do ./xcpenc -h for help function
=> Enable EXTRA_CREIT to view -C option in help function
=> help function define only in ./xcpenc 

NEW FILES INCLUDED :

1. /usr/src/hw1-amahajan/CSE-506
	1.1 Makefile
	1.2 install_module.sh
	1.3 sys_xcpenc.c      : system call file
	1.4 xcpenc.c          : user level program with all checks in user
	1.5 xcpenc_nocheck.c  : user level program with no checks at all
	1.6 mystruct.h        : header file that includes user arguments structure which is used in
				both kernel level and user level.
	1.7 testscript.sh     : Master testscript that runs 12 sub test scripts starting from test01.sh ... test12.sh
	1.8 test01.sh to      : Sub scripts to check basic functionality  and negative testcases
	    test_ec12.sh
	1.9 testscript_ec.sh  : Master testscript that runs 10 sub test scripts to check EXTRA_CREDIT functionality
				starting from test_ec01.sh ... test_ec10.sh
	2.0 test_ec01.sh to   : Sub scripts to check EXTRA_CREDIT basic functionality and negative testcases
	    test_ec10.sh

2. /usr/src/hw1-amahajan/
	2.1 kernel.config

-------------------------------------------------------------------------------------------------------------------------------------------
NEW FILES GENERATED :

1.  /usr/src/hw1-amahajan/CSE-506
	1.1 log		      : This file is generated by testscripts. It contains all the screen logs scriptwise and testcases
				wise for better readbility and view all screen logs at one place
				are run.
	1.2 results           : This file is generated by testscripts. It contains the results, error number returned to script
				and whether input and output file is same or not. It is generated for better readability of all
				testscripts result at once place.
				 
-------------------------------------------------------------------------------------------------------------------------------------------
USER PROGRAM "xcpenc.c" :

1. It reads arguments using getopt() and populate the structure

2. Arguments checking : This user level program does all the arguments checking. Following arguments checks are handled:
	1.1 No arguments specified
	1.2 Multiple options are specified together => -c, -d, -e. I am using bitwise operation to set only 1 bit and using
			bitwise operation to check how many bits are set using => flag & (flag-1). If it value is 0 then only
			bit is set else error out.
	1.3 -p cannot be specified with -c
	1.4 empty names of  => password, input file name and output file name
	1.5 No option (-e or -d) specified with -p.
	1.6 Password length is less than 6 characters
	1.7 Password contains newline then remove newline from password
	1.8 Unknon options specified
	1.9 Missing argument for -p <password>

3. MD5 : I am using MD5 to generate 128 bits hash key from password and pass that to kernel in keybuf field of struct

-------------------------------------------------------------------------------------------------------------------------------------------
USER PROGRAM "xcpenc_nocheck.c"

	This program is to test if kernel handles all the bad pointers and arguments and flags checking. It reads arguments from
	command line using getopt and pass that to kernel as it is without any null or empty check.

-------------------------------------------------------------------------------------------------------------------------------------------
KERNEL MODULE "sys_xcpenc.c"

	This is the kernel module.

1. Arguments checking and other checks : 
	1.1 It does all the arguments checking that is done in User program xcpenc.c mentioned above and return accordingly
		 error values.
	1.2 It checks if key passed during encryption and decryption matches or not and then error out if not

2. Hashing : I am using SHA256 to hash 
		i) key passed from user program in case of xcpenc.c
		ii)password passed from user program xcpenc_nocheck.c which doesn't do anything

***NOTE : I am using SHA256 for EXTRA_CREDIT part 2 as most of the ciphers i have included uses more than 24 bytes and SHA256
	  can be used for that.

3. File Checks :
	1.1 I am checking if i/p and o/p have permissions and error out if not present.
	1.2 Error out if both i/p and o/p point to same file (Hardlink + symboliclink) (using inode number and super block)
	1.3 Delete partially written file using lock and vfs_unlink.
	1.4 If input, output files are not regular file then error out.

4. File permission:
	1.1 setting permissions of output file equal to input file after opening the output file.

3. Encryption/Decryption : I
	1.1 IV DATA : For normal flow i am using hardcoded value for ivdata as skcipher needs that.
	1.2 PREAMBLE : I am storing key value in preamble.

***NOTE : All encryption decryption realted allocation are bypassed for copy command to save memory and increase efficiency

4. Read/Write : 
	1.1 I am reading in chunks of PAGE_SIZE and if data read is less than PAGE_SIZE then that number of bytes are only written
	1.2 That chunks is sent for encryption/decryption and then written to file.

5. Implemented strcmp function and strlen in kernel module

***NOTE : used common functions and goto statements to avoid writing same code again and again.
***NOTE : created skcipher handle only once and then use that for encryption/ decryption in loops
 
-------------------------------------------------------------------------------------------------------------------------------------------

EXTRA_CREDIT : (done under #define EXTRA_CREDIT)
		I have done extra credit part 1 and part 2
	Supporting ciphers : aes | blowfish | des3_ede | serpent | cast5 | cast6 | camellia 

***NOTE : Enabled 8 ciphers in CTR mode with different key requirements and more can be used in the same approach without any issue
	  but enabled 8 only to give the basic concept of handling different key requirements of cipher

	1. Arguments :
		1.1 If -C is not passed during EXTRA_CREDIT, by default it uses "aes"  and store that in preamble"
		      So if during encryption -C is not passed but during decryption added -C "cipher name" it will error out.
		1.2 -C is specified with -c error out
		1.3 If no argument passed with -C, error out.
		1.4 If -e or -d not specified with -C error out.
		1.5 If -C cipher name specified are different during encryption and decryption


	2.  IVDATA : IV data is created using 8bytes of page number and 8 bytes of inode of encrypted file
		     I am storing only Inode number in preamble to SAVE MEMORY in file plus page number can be counted from 0 to
		     number of chunks read. I am copying values in IVDATA using :

		     memcpy((*ivdata), (void *)&pageno, 8);
                     memcpy((void *)((char *)(*ivdata) + 8),
		     
		     to access first 8 and next 8 bytes of data


	3. DIFFERENT KEY LENGTHS APPROACH : I am using SHA256 at kernel level to generate hash key. ALL the ciphers i enabled donot
		have minkeysize > 32 else i would have used SHA512 or larger one.

		Then i reallocate memory to key using krealloc (to SAVE MEMORY) depending upon cipher name.
		Foreg if aes key range is  [16, 32] then donot reallocate memory (to save if conditions and memory allocation)
			but des3_ede key range is [24, 24] reallocate memory to 24 bytes.
	
	4. Using if conditions of different ciphers in one function only (set_cipher_name) and calling that one time to save time
		spent on checking if conditions again on skcipher creation. Thats why in the same function i am setting
		cipher_full_name also (ctr-aes-aesni)that is used by skcipher handler. It will be different for different ciphers.

	5. PREAMBLE : Storing inode number for IV data as mentioned in point 2 and cipher name 


-------------------------------------------------------------------------------------------------------------------------------------------
TEST SCRIPTS :

	Added both normal running testcases and negative testcases which should error our
	Some of the test scripts are run on xcpenc.c 
	Rest are run on xcpenc_nocheck.c

1. Without Extra credit :
		I made a master testscript "testscript.sh" that runs 12 sub test scripts. All these sub testscripts store result
		in "result"  and screen logs of command run in "log" file

2. With EXTRA_CREDIT :
	Enable EXTRA_CREDIT in all three programs : xcpenc.c, xcpenc_nocheck.c, sys_cpenc.c
	=> Run testscript_ec.sh to run test scripts of EXTRA_CREDIT mode. 
	=> Results are stored in results_ec
	=> Screen logs are stored in log_ec
	{ results_ec and log_ec are better readibilty of which commands were run and what error and results got in one place}
-------------------------------------------------------------------------------------------------------------------------------------------

REFRENCES : 

Skcipher code taken from linux crypto api document : https://www.kernel.org/doc/html/v4.18/crypto/api-samples.html