In a recent article, "Adviser Guides Obama Into the Google Age" , which was published by the New York Times on January 3, 2015, a former Google executive Megan Smith tries to resolve a culture clash of the Obama Administration as she works as the CTO (Chief Technology Officer). She attempts to solve the government's technology problems and upgrade still-used, ancient technology such as floppy disks.
Suppose that you're a paranoid person that wishes to keep secret data safe. How do you keep the data secure?
Write a simple toy program (wc
) that can be trusted.
The program must be secure, so we have to write our own program to ensure that. We're so paranoid to the point that we cannot trust the Linux kernel or any Ubuntu distribution.
In addition, we cannot trust any operating system out there. However, what type of hardware is going to be run on when the following is run?
wc foo.txt
We assume that the machine has the following characteristics.
jmp
instruction to our wc
program, but that would be quite expensive.
Instead, we will put the program on hard drive. The instruction pointer will point to an instruction to read the first 40 KiB, containing the program, on disk.
#/bin/sh
foo = bar
# Loads a different program
exec sed "s/foo/$foo/g"
wc
program
The disk controller indirectly connects the disk. It has a cache that remembers data written onto disk. The CPU sends disk commands to the disk controller in the form of x86 instructions.
inb - takes in an address as an argument, grabs the byte from the disk controller, and stuffs it into that register.
outb - takes in an address, grabs the byte from the disk controller, and outputs a specified number of bytes.
The BIOS reads sector into 0x7c00.
The following are the steps to read a sector from disk.
void main(void){ // boot loader
for (int i = 0; i < 80; i++) // 40 KiB = 80 sectors
read_ide_sector(i + 100, 0x20000 + i * 52);
goto *0x20000;
}
void read_ide_sector(int s, int a){
wait_for_ready();
outb(0x1f2, 1);
for (int i = 0; i < 4; i++)
outb(0x1f3 + i, (s >> (8 * i)) & 0xff);
outb(0x1f7, 0x20);
wait_for_ready();
insl(0x1f0, a, 128); // Copies data 4 bytes at a time
}
void wait_for_ready(void){
while ((inb(0x1f7) & 0xc0) != 0x40)
continue;
}
void main(void){
long long int nwords = 0;
bool inword = false;
int s = 90000;
int len;
do{
char buf[513];
buf[512] = 0;
read_ide_sector(s++, (int) buf);
len = strlen(buf);
nwords += cws(buf, len, &inword);
}while (len == 512);
display_ans(nwords);
}
int cws(char *buf, int bufsize, bool *inword){
int w = 0;
for (int i = 0; i < bufsize; i++){
bool alpha = isalpha((unsigned char) buf[i]);
w += alpha & !*inword;
*inword = alpha;
}
return w;
}
void display_ans(long long int nwords){
char* screen = 0xB8000 + 200;
do{
screen[0] = (nwords % 10) + 0;
screen[1] = 7; // grey on black
screen -= 2;
}while ((nwords /= 10) != 0);
}
read_ide_sector
return a bool
.