piekill / os_homework1

xcrypt

Repository from Github https://github.compiekill/os_homework1Repository from Github https://github.compiekill/os_homework1

				CSE 506 HW1
			        Junxing Yang
				Feb 22, 2012.
Overview
--------
I've done the basic part of the project, EXTRA CREDIT A and part of B and C. 
What I have not done yet is how to make the following 3 ciphers work: des, des3_ebe and camellia. 
Also, the program cannot handle block size bigger that PAGE_SIZE due to the limit of the padding method.

Files submitted
---------------
- xcrypt.c:	kernel module code which implements the system call
- xcipher.c:	user-level code which calls the system call 
- xcrypt.h:	common header file used by both .c file
- Makefile:	makefile to generate module "xcrypt.ko" 
		and user-level program "xcipher"

SYSCALL implementation
----------------------
- Add the following code to arch/x86/kernel/syscall_table_32.S: .long sys_xcrypt
- Add the following code to arch/x86/include/asm/unistd_32.h: #define __NR_xcrypt  349
  Modify: #define NR_syscalls  350
- Add the following code to fs/read_write.c:
	asmlinkage long (*xcryptfxn) (void *args) = NULL;
	EXPORT_SYMBOL(xcryptfxn);
	asmlinkage long sys_xcrypt(void *args)
	{
		if(xcryptfxn == NULL)
			return -ENOSYS;
		return xcryptfxn(args);
	}
	EXPORT_SYMBOL(sys_xcrypt);
- Declare function sys_xcrypt in arch/x86/include/asm/syscalls.h
- recompile the kernel.

Design decisions
----------------
@USER LEVEL:
(1) KEY:
use function int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, 
                                   unsigned char *salt, int saltlen, int iter, 
                                   int keylen, unsigned char *out); 
from OPENSSL to generate key in arbitrary length (Default value is 16 bytes).

(2) ARGUMENTS:
Use getopt(3) to get the arguments. Use function filter_copy() to delete '\n' from password.
Check whether the arguments are right:
- must specify -e or -d and only one of them
- whether input file exists
- if output file exists, ask user whether to overwrite or not
- whether password, input file name, output file name are null
(EXTRA:)
Use check_keylen_blksize() to check whether the key length and block size are appropriate.
For example, aes accepts key length 128,192,256 bits, and block size a multiple of 16 bytes.

@MODULE
(1) KEY:
Module uses the key from the user-level to do the en/decryption, and hash the key into the preamble (preamble->check_key) using MD5.

(2) PREAMBLE:
struct cipher_preamble {
	char check_key[MD5_DIGEST_SIZE];
#ifdef EXTRA_CREDIT
#define IV_SIZE 16
	char iv[IV_SIZE];
	int cipher_type;
	int blk_size;
#endif
}
The first 8 bytes of iv is the page number where we're doing encrypting;
the second 8 bytes is the inode number of the output file.

(3) OUTPUT FILE:

0                  16    32           36           40
---------------------------------------------------------------------------------
| check_key(hashed) | IV | cipher type | block size | encrypted bytes | padding |
---------------------------------------------------------------------------------

(4) EN/DECRYPTION and PADDING
Encryption,decryption and padding method come from the code in net/ceph/crypto.c
Padding method:
	size_t zero_padding = (0x10 - (src_len & 0x0f));
	char pad[PAD_SIZE];//PAD_SIZE is 16 by default
	memset(pad, zero_padding, zero_padding);
So for example if (PAD_SIZE - src_len) is 0x0B, it pads 11 "0x0B"s -- "BBBBBBBBBBB".

Module Program Flow
-------------------
- check the address of the argument passing to the module (using access_ok());
- copy the arguments to the kernel;
- check whether they are right arguments;
- set preamble;
- open the input file;
- if it's decryption, check whether the input file contains the right key (with the right cipher),and also get the iv and the block size.
- open the output file with flag O_CREAT, and set the permission to be S_IRUSR|S_IWUSR,
  but don't truncate(you don't want to truncate an outfile if it is also an infile);
- check whether input file and output are the same;
- truncate the output file;
- if it's encryption, set the iv in preamble;
- initialize the cipher;
- allocate input and output buffer;
- start en/decryption;
- if something goes wrong and there's a partial file, delete it.

ERRNO
-----
I use default errno and default error messages in most cases, except that I use EDOM to indicate that en/decryption failed. I find a errno for invalid key that is EKEYREJECTED with the default message "Key was rejected by service". Other errno and messages should be straightforward.

About

xcrypt


Languages

Language:C 100.0%