Ejemplo n.º 1
0
asmlinkage long xconcat(void *arg)
{
	/* dummy syscall: returns 0 for non null, -EINVAL for NULL */
	int i;
	struct file_details *details=(struct file_details *)arg; 
	int len=5;
	int read_bytes=len;
	int startPos=0;
	int write_bytes=0;
	char *buf;
	int total_bytes_written=0;
	int total_bytes_read=0;
	int percent_data_written=0;
	int total_files_written=0;
	printk("Creating file %s",details->outfile);
	wrapfs_create_file(details->outfile,details->oflags,details->mode);
		
	for(i=0;i<details->infile_count;i++){
		printk("Reading file %s\n", details->infiles[i]);
		startPos=0;
		read_bytes=len;
		while(read_bytes==len){
			buf=vmalloc(len);
			read_bytes=wrapfs_read_file(details->infiles[i],(void *) buf,len,startPos );
			printk("%s %d\n",buf,read_bytes);
			write_bytes=wrapfs_write_file(details->outfile,(void *)buf,len);
			startPos+=read_bytes;
			total_bytes_read+=read_bytes;
			total_bytes_written+=write_bytes;
			vfree(buf);
		}
		total_files_written+=1;
	}

	
	if(details->flags==0x00){
		return total_bytes_written;
	}else if(details->flags==0x01){
		return total_files_written;
	}else if(details->flags==0x02){
		percent_data_written=(total_bytes_written/total_bytes_read)*100;
		return percent_data_written;
	}
}
Ejemplo n.º 2
0
int encrypt_file_helper(struct file *input, struct file *output, char *key, int keylen,int flag, char *algo_name)
{
    //mm_segment_t oldfs;
    //loff_t offset=0;
    //loff_t pos=0;
    int readBytes = 0;
    int writtenBytes = 0;
    int size_of_input_file = 0;
    int actual_length_to_be_used = 0;
    int return_value = 0;
    int i;
    /* 0 means don't clean, 1 means clean */
    int clean_output_file = 0;
    ssize_t *length_encrypted = kmalloc(sizeof(ssize_t), GFP_KERNEL);
    /* buffers for transfers */
    char *from = kmalloc(PAGE_SIZE, GFP_KERNEL);
    char *to = kmalloc(PAGE_SIZE, GFP_KERNEL);
    
    /* let's check if kmalloc has worked */
    if(from == NULL || to == NULL)
    {
        return_value = -ENOMEM;
        printk("Error in allocating space for buffers\n");
        goto cleanup_this_house;
    }

    size_of_input_file = input->f_dentry->d_inode->i_size;


    /* When decrypting, we move the input file pointer 16 spaces and also verify the key as well */
    if (flag == 0)
    {
        memset(from,'\0', PAGE_SIZE);
        readBytes = wrapfs_read_file(input, from, 16);
        if(readBytes <= 0)
        {
            return_value = readBytes; //error returned by the read method.
            clean_output_file = 1; //remove partial output file
            goto cleanup_this_house;
        }
        /* Let's compare the key */
        for (i = 0; i < SIZE_OF_KEY_BUFFER; i++)
        {
            if (from[i] != key[i])
            {
                printk(KERN_CRIT "Key entered and preamble on the input file don't match\n");
                return_value = -EINVAL;
                clean_output_file = 1;
                goto cleanup_this_house;
            }
        }
        input->f_pos = 16;
        printk(KERN_CRIT "Key matched successfully\n");

    }
    
    /* This is the preamble portion, where we write the key on the file */
    if (flag == 1)
    {
        printk(KERN_CRIT "Writing key on the output file\n");
        if ((writtenBytes = wrapfs_write_file(output, key, 16)) <1)
        {
            printk(KERN_CRIT "Error while writing key on the output file.\n");
            return_value = -EIO;
            clean_output_file = 1;
            goto cleanup_this_house;
        }
        output->f_pos = 16;
        printk(KERN_CRIT "Preamble written successfully on the output file\n");

    }
    
    /* if decryption, then total bytes are reduced by 16, coz 16 is the preamble */
    if(flag == 0)
        size_of_input_file = size_of_input_file - 16;
    
    printk(KERN_CRIT "*******************************\n");
    printk(KERN_CRIT "We are ready to encrypt/decrypt\n");
    printk(KERN_CRIT "*******************************\n");

    /* Main while loop, that reads, en/de crypt and then writes */
    while(size_of_input_file > 0)
    {
        actual_length_to_be_used = 0;
        readBytes = 0;
        writtenBytes = 0;
        memset(from, '0', PAGE_SIZE);
        memset(to, '0', PAGE_SIZE);
        
        /* if decryption flag is specified */
        if (flag == 0)
        {
            if (size_of_input_file > (PAGE_SIZE))
            {
                actual_length_to_be_used = PAGE_SIZE;
                size_of_input_file = size_of_input_file - actual_length_to_be_used ;
            }
            else
            {
                actual_length_to_be_used = size_of_input_file;
                size_of_input_file = 0;
            }
        }
        
        /* 16 bytes are used for preamble, so set the buffer that will be en/de crypted according to the flag */
        if (flag == 1)
        {
            
            if (size_of_input_file > (PAGE_SIZE - 16))
            {
                actual_length_to_be_used = PAGE_SIZE - 16;
                size_of_input_file = size_of_input_file - actual_length_to_be_used ;
            }
            else
            {
                actual_length_to_be_used = size_of_input_file;
                size_of_input_file = 0;
            }
        }
        
        
        /* reading bytes depending upon the appropriate size */
        readBytes = wrapfs_read_file(input, from, actual_length_to_be_used);
        if(readBytes <= 0)
        {
            return_value = readBytes; //error returned by the read method.
            clean_output_file = 1;
            goto cleanup_this_house;
        }
        
        /* encrypt */
        if(flag ==1)
        {
            printk(KERN_CRIT "Encrypting...\n");
            return_value = encrypt_data(key, keylen, to, from, length_encrypted, actual_length_to_be_used, algo_name);
            if(return_value < 0)
            {
                printk(KERN_CRIT "cypto_blkcipher Encryption Failed.\n");
                clean_output_file = 1;
                goto cleanup_this_house;
            }
        }
        
        /* dencrypt */
        if(flag ==0)
        {
            printk(KERN_CRIT "Decrypting...\n");
            return_value = decrypt_data(key, keylen, to, from, length_encrypted, actual_length_to_be_used, algo_name);
            if(return_value < 0)
            {
                printk(KERN_CRIT "cypto_blkcipher Decryption Failed.\n");
                clean_output_file = 1;
                goto cleanup_this_house;
            }
        }
        writtenBytes = wrapfs_write_file(output, to, *length_encrypted);
        if(writtenBytes <=0)
        {
            return_value = writtenBytes; //error returned by the write method.
            clean_output_file = 1;
            goto cleanup_this_house;
        }
        
        
    }

    
cleanup_this_house:
    kfree(to);
    kfree(from);
    //set_fs(oldfs);
    return return_value;
    
}
Ejemplo n.º 3
0
asmlinkage long xcrypt(void *arg)
{
    if (arg == NULL) {
	printk("User level argument is NULL\n");
	return -EINVAL;
    } else {
	struct myargs *arguments;
	int result, paddedresult, padvalue, preambleWritten, temp, paddingWritten, paddingRead;
	struct file *filp=NULL, *filp1=NULL;
	struct dentry *dentry=NULL, *olddentry=NULL, *newdentry=NULL;
	long int inputFileLen=-1, outputFileLen=-1, keyLen=-1;
	char *srcbuffer, *destbuffer, *padding, *keyFromFile=NULL, *md5_hash=NULL, *tempOutFile;
	umode_t inputFileMode, outputFileMode;
	bool outFileCreated=false, renamed=false, success = false;
	int err=0;	
	arguments = (struct myargs *)kmalloc(sizeof(struct myargs), GFP_KERNEL);
	if (arguments==NULL) {
	    printk("Failed to allocate kernel memory\n");
	    err = -ENOMEM;
	    goto out1;
	}
	result = copy_from_user((void *)arguments, arg, sizeof(struct myargs));
	if(result!=0) {
	    printk("Copying from user failed\n");
	    err = -EFAULT;
	    goto out2;
	}
	if (((struct myargs*)arg)->inputFile == NULL) { /*Checking whether user passed NULL input File*/
	    printk("user level input file argument is NULL\n");
	    err = -EINVAL;
	    goto out2;
	}
	inputFileLen = strnlen_user(((struct myargs*)arg)->inputFile, 32767); //TODO get the maximum value from getname 
	if (inputFileLen == -1) {
	    printk("Finding User inputFile string length Failed\n");
	    err = -EFAULT;
	    goto out2;
	}
	arguments->inputFile = (char *)kmalloc(inputFileLen*sizeof(char), GFP_KERNEL);
	if ((arguments->inputFile)==NULL) {
            printk("Failed to allocate kernel memory for input file\n");
            err = -ENOMEM;
	    goto out2;
        }
	result = strncpy_from_user(arguments->inputFile, ((struct myargs*)arg)->inputFile, inputFileLen);
	if(result!=(inputFileLen-1)) {
            printk("Copying input file string from user failed\n");
            err = -EFAULT;
	    goto out3;
        }
	if((arguments->inputFile)==NULL) {
	    printk("Copying input file string from user failed\n");
	    err = -EFAULT;
	    goto out3;
	}
	if (((struct myargs*)arg)->outputFile == NULL) {
            printk("user level output file argument is NULL\n");
            err = -EINVAL;
	    goto out3;
        }
	outputFileLen = strnlen_user(((struct myargs*)arg)->outputFile, 32767); //TODO get the maximum value from getname
	if (outputFileLen == -1) {
            printk("Finding User outputFile string length Failed\n");
            err = -EFAULT;
	    goto out3;
        }
	arguments->outputFile = (char *)kmalloc(outputFileLen*sizeof(char), GFP_KERNEL);
	if ((arguments->outputFile)==NULL) {
            printk("Failed to allocate kernel memory for outputfile\n");
            err = -ENOMEM;
	    goto out3;
        }
	result = strncpy_from_user(arguments->outputFile, ((struct myargs*)arg)->outputFile, outputFileLen);
	if(result!=(outputFileLen-1)) {
            printk("Copying output file string from user failed\n");
            err = -EFAULT;
	    goto out4;
        }
	if((arguments->outputFile)==NULL) {
            printk("Copying output file string from user failed\n");
            err = -EFAULT;
	    goto out4;
        }
	if (((struct myargs*)arg)->keyBuf == NULL) {
            printk("user level key buffer argument is NULL\n");
            err = -EINVAL;
            goto out4;
        }
	keyLen = strnlen_user(((struct myargs*)arg)->keyBuf, 32767); //TODO get the maximum value from getname
        if (keyLen == -1) {
            printk("Finding User keyBuf string length Failed\n");
            err = -EFAULT;
	    goto out4;
        }
	arguments->keyBuf = (char *)kmalloc(keyLen*sizeof(char), GFP_KERNEL);
	if ((arguments->keyBuf)==NULL) {
            printk("Failed to allocate kernel memory\n");
            err = -ENOMEM;
	    goto out4;
        }
	result = strncpy_from_user(arguments->keyBuf, ((struct myargs*)arg)->keyBuf, keyLen);
	if(result!=(keyLen-1)) {
            printk("Copying key buf string from user failed\n");
            err = -EFAULT;
	    goto out5;
        }
	if((arguments->keyBuf)==NULL) {
            printk("Copying key buf string from user failed\n");
            err = -EFAULT;
	    goto out5;
        }

	if (strlen(arguments->keyBuf) != arguments->keyLen) {
	    printk("User key buffer length and kernel key buffer lengths differ\n");
	    err = -EINVAL;
	    goto out5;
	}

	if((arguments->flags)!=0 && (arguments->flags)!=1) {
	    printk("Invalid values for flag argument, it should be either 1 or 0\n");
	    err = -EINVAL;
	    goto out5;
	}

	srcbuffer = (char *)kmalloc((PAGE_SIZE+1)*sizeof(char), GFP_KERNEL);
	if (srcbuffer==NULL) {
	    printk("Failed to allocate kernel memory for srcbuffer\n");
            err = -ENOMEM;
	    goto out5;
	}
        
        destbuffer = (char *)kmalloc((PAGE_SIZE+1)*sizeof(char), GFP_KERNEL);
        if (destbuffer==NULL) {
            printk("Failed to allocate kernel memory for destbuffer\n");
            err = -ENOMEM;
	    goto out6;
        }

	padding = (char *)kmalloc(4*sizeof(char), GFP_KERNEL);
	if (padding==NULL) {
	    printk("Failed to allocate kernel memory for padding\n");
            err = -ENOMEM;
	    goto out7;
	}

        initialisePadding(padding); /*Initialising the padding array to all 0's */
        
	result=PAGE_SIZE;

	filp = filp_open(arguments->inputFile, O_RDONLY, 0);
	if (PTR_ERR(filp)==-ENOENT) {
	    printk("Input File doesnot exists\n");
	    err = -ENOENT; 
	    goto out8;
	} else {
	    printk("Input File exists\n");
	}
	
        if (!filp || IS_ERR(filp)) {
            printk("Read error for input file %d\n", (int) PTR_ERR(filp));
            err = PTR_ERR(filp);
	    goto out8;
        }

	inputFileMode = filp->f_inode->i_mode;

	if(!S_ISREG(inputFileMode)) {
	    printk("Input File is not a regular file\n");
	    err = -EISDIR;
	    goto out9;
	}

	if (!filp->f_op->read) {
	    printk("Error in reading input file\n");
            err = PTR_ERR(filp);
	    goto out9;
	}

	filp1 = filp_open(arguments->outputFile, O_WRONLY, 0);
	if (PTR_ERR(filp1)==-ENOENT) {
            printk("Output File doesnot exists, creating it\n");
	    filp1 = filp_open(arguments->outputFile, O_CREAT, inputFileMode); /*Creating output file if it doesnot exists with input file permissions*/
	    if(!filp1 || IS_ERR(filp1)) {
		printk("Error in creating output file\n");
		err = PTR_ERR(filp1);
		goto out8_1;
	    } else {
		printk("Output File created succesfully\n");
		outFileCreated = true;
	    }
        } else {
            printk("Output File exists\n");
        }

	if(!outFileCreated) {
	    if(!filp1 || IS_ERR(filp1)) {
		printk("Error in opening output file\n");
		err = PTR_ERR(filp1);
                goto out8_1;
	    }
	}

	if(!outFileCreated) {
	    outputFileMode = filp1->f_inode->i_mode;
	
	    if(!S_ISREG(outputFileMode)) {
                printk("Output File is not a regular file\n");
                err = -EISDIR;
		goto out9;
            }
	}

	if(!outFileCreated) {
	    if (filp->f_inode->i_ino == filp1->f_inode->i_ino) {
	        printk("Both input and output files are same, they should be different\n");
	        err = -EPERM;
		goto out9;
 	    }
	}
	
	if(!outFileCreated) {
	    olddentry = filp1->f_path.dentry;
            filp_close(filp1, NULL);
	    tempOutFile =  (char *)kmalloc((strlen(arguments->outputFile)+5)*sizeof(char), GFP_KERNEL);
	    strncpy(tempOutFile, arguments->outputFile, strlen(arguments->outputFile));
	    strcat(tempOutFile, ".tmp");
	    tempOutFile[(strlen(arguments->outputFile)+5)]='\0';
	    filp1 = filp_open(tempOutFile, O_WRONLY, 0);
            if (PTR_ERR(filp1)==-ENOENT || IS_ERR(filp1)) {
                printk("temp Output File doesnot exists, creating it\n");
            } else {
                printk("temp output File exists, truncating and creating new one\n");
		dentry = filp1->f_path.dentry;
		filp_close(filp1, NULL);
		err = file_unlink(dentry->d_parent->d_inode, dentry);
		if(err != 0) {
		    printk("unlink of already existing temporary file failed\n");
		    err = -EBUSY;
		    goto out9;
		}
		printk("unlink function returned : %d\n", err);
            }
            filp1 = filp_open(tempOutFile, O_CREAT, outputFileMode);
            if(!filp1 || IS_ERR(filp1)) {
                printk("Error in creating temp output file\n");
                err = PTR_ERR(filp1);
		goto out8_1;
            } else {
                printk("temp output File created succesfully\n");
            }
	}
	
	newdentry = filp1->f_path.dentry;

	if (!filp1 || IS_ERR(filp1)) {
            printk("Write error for output file %d\n", (int) PTR_ERR(filp1));
            err = PTR_ERR(filp1);
	    goto out10;
        }

        if (!filp1->f_op->write) {
	    printk("Error in writing to temp output file\n");
            err = PTR_ERR(filp1);
	    goto out10;
	}

	md5_hash = kmalloc(17*sizeof(char), GFP_KERNEL);
	if (md5_hash==NULL) {
            printk("Failed to allocate kernel memory for key from file\n");
            err = -ENOMEM;
	    goto out10;
        }
        err = generate_md5(arguments->keyBuf, md5_hash, strlen(arguments->keyBuf));
	if(err != 0) {
	    printk("kernel MD5 generation failed\n");
	    goto out11;
	}
	md5_hash[strlen(arguments->keyBuf)] = '\0';
        
	if (arguments->flags) { //ENCRYPTION
	    preambleWritten = wrapfs_write_file(filp1, (void *)(md5_hash), strlen(md5_hash)); /*Writing Key hash to the file*/	   
	    if(preambleWritten < 0) {
		printk("Writing preamble failed\n");
		err = -EFAULT;
		goto out11;
	    }
	    paddingWritten = wrapfs_write_file(filp1, (void *)(padding), 4); /*Writing Inital Padding to the file*/
	    if (paddingWritten < 0) {
		printk("Writing padding failed\n");
                err = -EFAULT;
		goto out11;
	    }
	    while(result==PAGE_SIZE) {
	        result = wrapfs_read_file(filp, (void *)srcbuffer, PAGE_SIZE);
		if(result < 0) {
		    printk("Reading from input file failed\n");
                    err = -EFAULT;
		    goto out11;
		}
	        err = encrypt_Cipher(arguments->keyBuf, srcbuffer, destbuffer, result, &paddedresult);
		if (err < 0) {
		    printk("Error occured while encrypting\n");
		    goto out11;
		}
	        if(paddedresult!=result) {
		    padvalue = paddedresult - result;
		    buildPadding(padding, padvalue);
		    result = paddedresult;
	        }
	        result = wrapfs_write_file(filp1, (void *)destbuffer, result);
		if (result < 0) {
		    printk("Writing to output file failed\n");
                    err = -EFAULT;
		    goto out11;
		}
	    }
	    paddingWritten = wrapfs_write_file_pos(filp1, (void *)padding, 4, preambleWritten);
	    if (paddingWritten < 0) {
                printk("Writing padding failed\n");
                err = -EFAULT;
		goto out11;
            }
	} else {  //DECRYPTION
	    keyFromFile = kmalloc(16*sizeof(char), GFP_KERNEL);
	    if (keyFromFile==NULL) {
                printk("Failed to allocate kernel memory for key from file\n");
                err = -ENOMEM;
		goto out11;
            }
	    temp = wrapfs_read_file(filp, (void *)keyFromFile, strlen(md5_hash));
	    if (temp != strlen(md5_hash)) {
		printk("reading key from file failed\n");
		err = -EFAULT;
		goto out12;
	    }
	    if (compareKeys(md5_hash, keyFromFile, temp)) {
		printk("Both Keys Match\n");
	    } else {
		printk("Both keys doesnot match\n");
		err = -EINVAL; //TODO : Return proper error Value.
		goto out12;
	    }
	    paddingRead = wrapfs_read_file(filp, (void *)padding, 4);
	    if(paddingRead < 0) {
		printk("Reading padding failed\n");
                err = -EFAULT;
		goto out12;
	    }
	    padvalue = reconstructPadding(padding);
	    if (padvalue < 0) {
		printk("Reconstructing padding value failed(negative value not acceptable)\n");
                err = -EFAULT;
		goto out12;
	    }
	    printk("Pad value returned : %d\n", padvalue);
	    while(result==PAGE_SIZE) {
                result = wrapfs_read_file(filp, (void *)srcbuffer, PAGE_SIZE);
		if (result < 0) {
		    printk("Reading from input file failed\n");
                    err = -EFAULT;
		    goto out12;
		}
                printk("result read from file : %u\n", result);
                err = decrypt_Cipher(arguments->keyBuf, srcbuffer, destbuffer, result);
		if (err < 0) {
                    printk("Error occured while encrypting\n");
                    goto out12;
                }	
		if (result<PAGE_SIZE) {
		    result = result - padvalue;
		}
                result = wrapfs_write_file(filp1, (void *)destbuffer, result);
		if(result < 0) {
		    printk("writing to output file failed\n");
                    err = -EFAULT; //TODO goto
		    goto out12;
		}
            }
	}
	if(!outFileCreated) {
	    err = file_rename(newdentry->d_parent->d_inode, newdentry, olddentry->d_parent->d_inode, olddentry);
	    if(err!=0) {
		printk("renaming of tempfile to output file failed\n");
                err = -EBUSY;
		goto out12;
	    } else
		renamed = true;
        } else
	    success = true;

out12:
	if(keyFromFile)
	    kfree(keyFromFile);
out11:
	kfree(md5_hash);
out10:
	if(filp1)
	    filp_close(filp1, NULL);
	if((!renamed && !outFileCreated)||(!success && outFileCreated))
	    file_unlink(newdentry->d_parent->d_inode, newdentry);
out9:
	if(filp1)
	    filp_close(filp1, NULL);
out8_1:
	if(filp)
	    filp_close(filp, NULL);
out8:
	kfree(padding);
out7:
	kfree(destbuffer);
out6:
	kfree(srcbuffer);
out5:
	kfree(arguments->keyBuf);
out4:
	kfree(arguments->outputFile);
out3:
	kfree(arguments->inputFile);
out2:
 	kfree(arguments);
out1:
	return err;
    }
}