Added OS II assignments

This commit is contained in:
2018-06-08 00:50:59 -07:00
parent 43b3555da8
commit 06c37d59e1
76 changed files with 103393 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
\section{Design}
The framework for the device driver was taken from the "simple block device" from the website: http://blog.superpat.com/2010/05/04/a-simple-block-driver-for-linux-kernel-2-6-31/. The following changes were then needed to add crypto functionality:
\begin{itemize}
\item Addition of cipher
\item Addition of cipher key
\item Addition of module parameter for the key
\item Change the read and write functionality so that the encryption and decryption occurs as the reads and writes happen
\end{itemize}
The following psuedocode describes how the read and write functionality with encryption and decryption was implemented:
\begin{lstlisting}[lineskip=3pt,keywords={if,else,while}]
if (write) {
for(iterate through desired length) {
encrypt using crypto_cipher_encrypt_one()
}
}
else {
for(iterate through desired length) {
decrypt using crypto_cipher_decrypt_one()
}
}
\end{lstlisting}

View File

@@ -0,0 +1,254 @@
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/drivers/block/encrypted_block_device.c linux-yocto-3.19.2/drivers/block/encrypted_block_device.c
--- linux-yocto-3.19.2_untouched/drivers/block/encrypted_block_device.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-yocto-3.19.2/drivers/block/encrypted_block_device.c 2018-05-16 21:34:04.762216256 -0700
@@ -0,0 +1,226 @@
+/*
+ * Encrypted block driver by Corinna Brown and Corwin Perren
+ *
+ * Core code pulled from the following link
+ * http://blog.superpat.com/2010/05/04/a-simple-block-driver-for-linux-kernel-2-6-31/
+ *
+ * A sample, extra-simple block driver. Updated for kernel 2.6.31.
+ *
+ * (C) 2003 Eklektix, Inc.
+ * (C) 2010 Pat Patterson <pat at superpat dot com>
+ * Redistributable under the terms of the GNU GPL.
+ */
+
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+
+ #include <linux/kernel.h> /* printk() */
+ #include <linux/fs.h> /* everything... */
+ #include <linux/errno.h> /* error codes */
+ #include <linux/types.h> /* size_t */
+ #include <linux/vmalloc.h>
+ #include <linux/genhd.h>
+ #include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/crypto.h>
+
+MODULE_LICENSE("Dual BSD/GPL");
+static char *Version = "1.4";
+
+static int major_num = 0;
+module_param(major_num, int, 0);
+static int logical_block_size = 512;
+module_param(logical_block_size, int, 0);
+static int nsectors = 1024; /* How big the drive is */
+module_param(nsectors, int, 0);
+
+/* Cryptography Assignment Variables */
+
+struct crypto_cipher *custom_cipher;
+
+static char *custom_cipher_key = "3a84e1ac6b54ca";
+module_param(custom_cipher_key, charp, 0644);
+
+
+/*
+ * We can tweak our hardware sector size, but the kernel talks to us
+ * in terms of small sectors, always.
+ */
+#define KERNEL_SECTOR_SIZE 512
+
+/*
+ * Our request queue.
+ */
+static struct request_queue *Queue;
+
+/*
+ * The internal representation of our device.
+ */
+static struct sbd_device {
+ unsigned long size;
+ spinlock_t lock;
+ u8 *data;
+ struct gendisk *gd;
+} Device;
+
+/*
+ * Handle an I/O request.
+ */
+static void sbd_transfer(struct sbd_device *dev, sector_t sector,
+ unsigned long nsect, char *buffer, int write) {
+ unsigned long offset = sector * logical_block_size;
+ unsigned long nbytes = nsect * logical_block_size;
+
+ unsigned char *device_buffer = dev->data + offset;
+ unsigned char *request_buffer = buffer;
+ int i;
+
+ int custom_cipher_length = sizeof(custom_cipher_key) /
+ sizeof(custom_cipher_key[0]);
+
+ printk("##[GROUP4]## Custom cipher key is %s\n", custom_cipher_key);
+ crypto_cipher_setkey(custom_cipher, custom_cipher_key, custom_cipher_length);
+
+ if ((offset + nbytes) > dev->size) {
+ printk (KERN_NOTICE "sbd: Beyond-end write (%ld %ld)\n", offset, nbytes);
+ return;
+ }
+
+ printk("##[GROUP4]## Module is: %s\n", write ? "WRITING" : "READING");
+ if (write)
+ {
+ for (i = 0; i < nbytes; i+= crypto_cipher_blocksize(custom_cipher)) {
+ crypto_cipher_encrypt_one(custom_cipher, device_buffer + i,
+ request_buffer + i);
+ }
+ }
+ else
+ {
+ for (i = 0; i < nbytes; i+= crypto_cipher_blocksize(custom_cipher)) {
+ crypto_cipher_decrypt_one(custom_cipher, request_buffer + i,
+ device_buffer + i);
+ }
+ }
+
+ printk("##[GROUP4]## Encrypted Bytes ##\n");
+ for (i = 0; i < nbytes; i++) {
+ printk("%u", (unsigned) *device_buffer++);
+ }
+ printk("\n");
+
+ printk("##[GROUP4]## Unencrypted Bytes ##\n");
+ for (i = 0; i < nbytes; i++) {
+ printk("%u", (unsigned) *request_buffer++);
+ }
+ printk("\n\n");
+}
+
+static void sbd_request(struct request_queue *q) {
+ struct request *req;
+
+ req = blk_fetch_request(q);
+ while (req != NULL) {
+ // blk_fs_request() was removed in 2.6.36 - many thanks to
+ // Christian Paro for the heads up and fix...
+ //if (!blk_fs_request(req)) {
+ if (req == NULL || (req->cmd_type != REQ_TYPE_FS)) {
+ printk (KERN_NOTICE "Skip non-CMD request\n");
+ __blk_end_request_all(req, -EIO);
+ continue;
+ }
+ sbd_transfer(&Device, blk_rq_pos(req), blk_rq_cur_sectors(req),
+ bio_data(req->bio), rq_data_dir(req));
+ if ( ! __blk_end_request_cur(req, 0) ) {
+ req = blk_fetch_request(q);
+ }
+ }
+}
+
+/*
+ * The HDIO_GETGEO ioctl is handled in blkdev_ioctl(), which
+ * calls this. We need to implement getgeo, since we can't
+ * use tools such as fdisk to partition the drive otherwise.
+ */
+int sbd_getgeo(struct block_device * block_device, struct hd_geometry * geo) {
+ long size;
+
+ /* We have no real geometry, of course, so make something up. */
+ size = Device.size * (logical_block_size / KERNEL_SECTOR_SIZE);
+ geo->cylinders = (size & ~0x3f) >> 6;
+ geo->heads = 4;
+ geo->sectors = 16;
+ geo->start = 0;
+ return 0;
+}
+
+/*
+ * The device operations structure.
+ */
+static struct block_device_operations sbd_ops = {
+ .owner = THIS_MODULE,
+ .getgeo = sbd_getgeo
+};
+
+static int __init sbd_init(void) {
+ /* Initialize our cipher_key */
+ custom_cipher = crypto_alloc_cipher("aes", 0, 0);
+
+ /*
+ * Set up our internal device.
+ */
+ Device.size = nsectors * logical_block_size;
+ spin_lock_init(&Device.lock);
+ Device.data = vmalloc(Device.size);
+ if (Device.data == NULL)
+ return -ENOMEM;
+ /*
+ * Get a request queue.
+ */
+ Queue = blk_init_queue(sbd_request, &Device.lock);
+ if (Queue == NULL)
+ goto out;
+ blk_queue_logical_block_size(Queue, logical_block_size);
+ /*
+ * Get registered.
+ */
+ major_num = register_blkdev(major_num, "sbd");
+ if (major_num < 0) {
+ printk(KERN_WARNING "sbd: unable to get major number\n");
+ goto out;
+ }
+ /*
+ * And the gendisk structure.
+ */
+ Device.gd = alloc_disk(16);
+ if (!Device.gd)
+ goto out_unregister;
+ Device.gd->major = major_num;
+ Device.gd->first_minor = 0;
+ Device.gd->fops = &sbd_ops;
+ Device.gd->private_data = &Device;
+ strcpy(Device.gd->disk_name, "sbd0");
+ set_capacity(Device.gd, nsectors);
+ Device.gd->queue = Queue;
+ add_disk(Device.gd);
+
+ return 0;
+
+out_unregister:
+ unregister_blkdev(major_num, "sbd");
+out:
+ vfree(Device.data);
+ return -ENOMEM;
+}
+
+static void __exit sbd_exit(void)
+{
+ del_gendisk(Device.gd);
+ put_disk(Device.gd);
+ unregister_blkdev(major_num, "sbd");
+ blk_cleanup_queue(Queue);
+ vfree(Device.data);
+}
+
+module_init(sbd_init);
+module_exit(sbd_exit);
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/drivers/block/Kconfig linux-yocto-3.19.2/drivers/block/Kconfig
--- linux-yocto-3.19.2_untouched/drivers/block/Kconfig 2018-05-04 15:14:54.159243368 -0700
+++ linux-yocto-3.19.2/drivers/block/Kconfig 2018-05-16 19:58:45.301219285 -0700
@@ -15,6 +15,9 @@
if BLK_DEV
+config BLK_DEV_EBD
+ tristate "Homework group4 encrypted block device driver."
+
config BLK_DEV_NULL_BLK
tristate "Null test block driver"
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/drivers/block/Makefile linux-yocto-3.19.2/drivers/block/Makefile
--- linux-yocto-3.19.2_untouched/drivers/block/Makefile 2018-05-04 15:14:54.159243368 -0700
+++ linux-yocto-3.19.2/drivers/block/Makefile 2018-05-16 19:59:05.919571039 -0700
@@ -30,6 +30,7 @@
obj-$(CONFIG_BLK_DEV_NBD) += nbd.o
obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
+obj-$(CONFIG_BLK_DEV_EBD) += encrypted_block_device.o
obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
obj-$(CONFIG_BLK_DEV_HD) += hd.o

View File

@@ -0,0 +1,98 @@
\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran}
\usepackage{graphicx}
\graphicspath{{./figures/}}
\usepackage{url}
\usepackage{setspace}
\usepackage{multicol}
\usepackage{pdflscape}
\usepackage{pdfpages}
\usepackage[british]{babel}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{hyperref}
\usepackage{subfig}
\usepackage{geometry}
\geometry{textheight=9.5in, textwidth=7in}
% \overfullrule=2in
%Personal \newcommands
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
\lstset{basicstyle=\ttfamily,
backgroundcolor=\color{backcolor},
showstringspaces=false,
commentstyle=\color{red},
keywordstyle=\color{blue},
columns=fullflexible,
breaklines=true,
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
}
\newcommand{\NameSigPair}[1]{
\par
\makebox[2.75in][r]{#1}
\hfill
\makebox[3.25in]{
\makebox[2.25in]{\hrulefill}
\hfill
\makebox[.75in]{\hrulefill}
}
\par\vspace{-12pt}
\textit{
\tiny\noindent
\makebox[2.75in]{}
\hfill
\makebox[3.25in]{
\makebox[2.25in][r]{Signature}
\hfill
\makebox[.75in][r]{Date}
}
}
}
% 3. If the document is not to be signed, uncomment the command below
\renewcommand{\NameSigPair}[1]{#1}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{titlepage}
\pagenumbering{gobble}
\begin{singlespace}
\par\vspace{2in}
\centering
\scshape{
\huge Operating Systems II Homework 3 \par
{\large\today}\par
\vspace{.5in}
\vfill
\vspace{5pt}
{\large Prepared by }\par
Group 4 \par
% 5. comment out the line below this one if you do not wish to name your team
\vspace{5pt}
{\Large
\NameSigPair{Corinna Brown}\par
\NameSigPair{Corwin Perren}\par
}
\vspace{20pt}
\begin{abstract}
The document is our group's submission for homework three covering the design of our solution, answers to explicit assignment questions, a version control log, and a work log.
\end{abstract}
}
\end{singlespace}
\end{titlepage}
\newpage
\pagenumbering{arabic}
\tableofcontents
\clearpage
\input{design}
\input{questions}
\input{versioncontrollog}
\input{worklog}
\end{document}

View File

@@ -0,0 +1,31 @@
# This config is copied from overleaf so output there will match compiled output here
# support for the glossaries package:
add_cus_dep('glo', 'gls', 0, 'makeglossaries');
add_cus_dep('acn', 'acr', 0, 'makeglossaries');
sub makeglossaries {
system("makeglossaries \"$_[0]\"");
}
# support for the nomencl package:
add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
sub makenlo2nls {
system("makeindex -s nomencl.ist -o \"$_[0].nls\" \"$_[0].nlo\"");
}
# from the documentation for V. 2.03 of asymptote:
sub asy {return system("asy \"$_[0]\"");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");
# metapost rule from http://tex.stackexchange.com/questions/37134
add_cus_dep('mp', '1', 0, 'mpost');
sub mpost {
my $file = $_[0];
my ($name, $path) = fileparse($file);
pushd($path);
my $return = system "mpost $name";
popd();
return $return;
}

View File

@@ -0,0 +1,19 @@
# Makefile created by Corwin Perren
# Generic makefile for all LaTeX projects downloaded from overleaf
#
# All this makefile does is call perl against latexmkrc, which is
# the latex equivalent of make
LATEXMK_COMPILE_FLAGS = -cd -pdf homework3.tex
LATEXMK_CLEAN_FLAGS = -c
.DEFAULT_GOAL := all
all: latexmk_output clean
latexmk_output:
perl latexmk.pl $(LATEXMK_COMPILE_FLAGS)
mv homework3.pdf CS444_project3_4.pdf
clean:
perl latexmk.pl $(LATEXMK_CLEAN_FLAGS)

View File

@@ -0,0 +1,17 @@
\section{Questions}
\subsection{Point of Assignment}
The main point of this assignment was to gain experience working with device drivers and the Linux kernel crypto API. To accomplish this, a lot of research was necessary. Learning how to perform research and finding good sources for the future are also benefits of this assignment. Finally, the assignment provided experience working with module parameters.
\subsection{Problem Approach}
We approached this problem by first reading through the Homework 3 page on Canvas. Then we separated the assignment into three main concepts, the device driver, crypto, and the module.
First we decided to implement the device driver. As suggested on the Canvas page, "SBD" was researched and an example of a sample block device was found at http://blog.superpat.com/2010/05/04/a-simple-block-driver-for-linux-kernel-2-6-31/. After some adjustments to ensure it was compatible with the version of the kernel we are using, the device driver was tested. After ensuring correct functionality of the device driver, the Linux kernel crypto API was researched. This mainly involved looking through the crypto.h file to find the functions that are available. After finding the functions we wished to use, the device driver was adapted to encrypt and decrypt data at the time that it is read or written. Finally, we added the cipher key as a module parameter. While performing the crypto development,the module was loaded as a built-in module at boot time. Once kernel parameters were added, the driver was compiled as an add-in module, scp'd to the virtual machine, installed into the kernel directories, and loaded with varying parameters as needed for testing.
\subsection{Correctness}
We know that the end result was correct by first using the output of printk function calls to look at the cipher key, the current state (reading or writing), the encrypted bytes, and the unencrypted bytes. This allowed us to see what the encrypted data looked like and ensure that the encryption and decryption was being done correctly. Then we moved our block device to a module to test the module parameter. To test this, we used different cipher keys with the same input data to show that the output data changes with the different cipher keys. Lastly, we were able to verify that the driver was working correctly by directly reading data from the /dev/sdb0 device. Reading from the device directly always returned garbage encrypted data unlike when reading from the mounted directory using our driver.
\subsection{What Was Learned}
We again learned that documentation is extremely important to code development as it allows readers to more easily use code that has already been written. We also learned the basics of how to use the Linux kernel crypto API as well as the basics of writing device drivers.
\subsection{How to Evaluate}
After applying the patch file using patch -p1 $<$ homework3.patch from the root of the kernel directory, building the kernel, and launching the vm, you should immediately see printk statements showing the output of the driver. Once booted, a filesystem can be made per the assignment instructions and mounted to a folder using the mount command. By reading and writing data to the mounted drive and watching printk output, you will easily be able to see that the encrypted data is different than the unencrypted data. For more in depth evaluation, a boot time kernel parameter can be set with the command "encrypted\_boot\_device.custom\_cipher\_key=yourkey" to change the module parameter. Then, by following the process above with identical data input as before, you can see the printk statements for encrypted data output differing data than with the default key.

View File

@@ -0,0 +1,8 @@
\section{Version Control Log}
\begin{center}
\begin{tabular}{l l l l} \textbf{Detail} & \textbf{Author} & \textbf{Date} &\textbf{Description}\\\hline
\href{.//commit/34ba569ad1c705e8d6054e20f0a129a21d2bc0c1}{34ba569} & Corwin Perren & 2018-05-16 21:45:55 -0700 &Finished homework 3\\\hline
\end{tabular}
\end{center}

View File

@@ -0,0 +1,14 @@
\section{Work Log}
\begin{itemize}
\item 2018-05-16
\begin{itemize}
\item Group met in Valley Library
\item Started Latex document for Homework 3
\item Found an example of a sbd
\item Updated sbd to work with correct kernel version
\item Researched Linux kernel API and searched through crypto.h
\item Added crypto functionality to the device driver
\item Added module parameter
\item Tested module
\end{itemize}
\end{itemize}