System calls are the fundamental API provided by an operating system
to application programs. For example, the read()
and
write()
system calls are the basic mechanisms for doing file
input and output in Linux. All other file I/O routines, such as C++'s stream
operators (<<
and >>
) or Python's
file methods (file.read()
and file.write()
)
are built upon these C-interface system calls.
To make sure we never take these high-level interfaces for granted, we're going to work with Linux's system calls directly! We will use Linux's file manipulation system calls to write a program that encrypts and decrypts files.
In this lab, you will:
open()
, close()
, read()
,
and write()
system calls to do file I/O
ecb_crypt()
GNU function to encrypt and decrypt
data, which implements a type of encryption called DES
encrypt
- encrypt or decrypt a file using DES encryption
encrypt <key> <input file> <output file> <mode>
key
: an 8 character string used as the DES key to encrypt/decrypt
input file
: the file to encrypt/decrypt
output file
: the result of the operation
mode
: specifies whether to encrypt or decrypt- if mode=0, then encrypt the input file, if mode=1 then decrypt the input file
encrypt
will encrypt and decrypt files using the GNU C library
function ecb_crypt()
. You must use the read()
and
write()
system calls (documented at man 2 read
and
man 2 write
, respectively) to read the input file and write to
the output file.
encrypt
detects the following errors and quits gracefully:
strtol()
)
open()
, close()
,
read()
, or write()
- use the
function perror()
to print useful error messages
Upon encountering any error, print a useful message and exit()
with a negative status code.
If no error is encountered then the program should not produce any output to standard output.
You can download these files to your local machine with the
wget
program from the Linux command line. See
man wget
for details.
ecb_crypt()
diff
program to compare files and highlight any
differences. This is an easy way to detect whether or not a decrypted file
is identical to the original source, especially when the files are too large
to inspect visually!
wc
program to count how many characters are in a
file.
read()
system call returns how many bytes it has read.
This is useful info needed for both ecb_crypt()
and write()
. Keep reading the input until read()
returns a 0 (end of
file) or -1 (error).
des_setparity()
function on your key
before using the encryption function. This is due to the mathematics of
the DES encryption algorithm implemented by ecb_crypt()
.
ecb_crypt()
function works on arbitrarily long arrays
of data, but the total size must be evenly divisible by 8. If your message
is not divisible by 8, then you will need to pad it with blank space ' '
characters.
diff
you will find a difference on
the last line. You can suppress this by using diff -Z
.
The following man pages will be useful:
open
(2)
close
(2)
read
(2)
write
(2)
ecb_crypt
(3)
des_setparity
(3)
atoi
(3)
strtol
(3)
strlen
(3)
perror
(3)
errno
(2)
exit
(2)
diff
(1)
wc
(1)
time
, which records how
long a command runs. Record how long it takes to encrypt the file test3
.
The syntax in this case is "time ./encrypt key
test3 outfile 0
". This will report three measurements: real, user,
and sys. How long does your program take to run in real time?
read()
system call controls
how many characters can be read at a time. Try modifying this parameter to
use a few different values: 8, 80, 800, and 4096. Record how long it takes to
encrypt test3
with each setting.
encrypt abcd1234 infile outfile 0 DES
should be equivalent to
encrypt abcd1234 infile outfile 0
However, specifying XOR encryption, as such:
encrypt 42 infile outfile 0 XOR
indicates that your program should encrypt the messages by bitwise XOR'ing each character in the input file with the number 42. Decryption is accomplished by XOR'ing each character in the encrypted file with the same value.
The fifth parameter must be one of DES, XOR, or blank. Any other value
should exit the program with a descriptive error message. The manual page
strcmp(3)
will probably be helpful. Attempting to use DES
encryption with an XOR key, or vice-versa, should result in a
descriptive error message and exit.
The encryption we have used in this program is very weak! Not only is it subject to brute force attacks, the particular variant we have used (ECB, which stands for Electronic Code Book) will always encrypt the same source data with the same ciphertext. Does this sound like a problem to you? Google "ecb penguin" to see what kinds of statistical information your supposedly encrypted file can leave!
The encryption program you've written should work on any type of file.
Try encrypting and decrypting different file types to see if this is really
the case. You should be able to use it on text, photos, videos,
even binary executable files! If you decrypt a binary executable file you
will need to mark it as executable with the command
"chmod u+x filename
"
Please submit your lab to your course git repository. Your code should be
entirely contained in a file called encrypt.c
, and your
question responses should be included in an appropriately named text file.