Steganography is 'hidden writing'. The way I see it, steganography is related to cryptography, where the interceptor of the data can't tell if there is any data there or not, let alone decrypt it.

Traditionally, the way this worked is where you may intercept a message like 'we are going on vacation next Friday'. So you don't know if it means what it means or if something is to be done next Friday or whatever. Or a prisoner writes a letter where the words in the letter don't matter, its the placement of the words on the page or choice of synonyms that are the coded message.

A typical computer implementation of this is to hide messages in the low order bits of a jpeg file. Since you can't perceive the minor color variations, the picture looks perfectly normal. So you use a normal symmetric cipher to encode your message, interspersed with amounts of random data. You end up with a bunch of random-looking bits. Now you stuff these bits in the low-order bits of jpegs of flowers or forests and send them. An interceptor can see that the low 1 or 2 bits of the pictures vary, but they would in the original pictures anyway. But a person with the encryption algorithm, the key, and who knows it's there can extract the data.

I don't use it to pass messages, I want to use it to store data on a disk but I don't want anyone to be able to tell the data is there. So my implementation goes like this:

You go to work at a top-secret underground facility. Your boss gave you three keys and told you that you work on levels 1, 2 and 3. He does not tell you how many levels there are. To get to level 3, you must pass through the door to levels 1 and 2. Every level, including the last level, has a door to the next level. (If you could blast through that last door, all that would be there is dirt.) Basically, there is no way to tell how many levels there are.

So I have a utility that fills a disk with random data. Then it partitions the disk into a maximum of 26 partitions, lettered a through z. Each partition has a different encryption key and a size that you supply. To get to partition c, you must also unlock a and b. If you have unlocked a, b and c, there is no way to tell that there is a partition d, as the disk was originally filled with random data, and the possible encrypted partition d cannot be distinguished from random data unless you have the key.

So the police confiscate your hard drive and see that you have the stego software on the system. So you confess the key for a, where you store your income tax return data. And they believe there is more, so after some coercion you give them the key for b, where you store your love letters. Maybe after they have 'reasoned' with you some more, you give them the keys to c and d (holding info that is increasingly confidential like secret bank account numbers), each time insisting there are no more. And so on, but your real data is in partition (insert your favourite letter here), but time is long since passed that your 'civil rights' have been violated. If they are going the legal route and get court orders, etc., say 'I gave you all there is (a,b,c), and you have to believe me as you can't prove there is any more (d,e,f,...)'.

This method has the advantage over the jpeg method in that it uses the space of the drive efficiently and you don't have to take a bunch of jpeg pictures (you can't use clip-art as they could find the originals and compare them). In either case they will find the stego software on your system, so they know that you have hidden data on the system, it's just a question of how much.

My commands are:

The oz_stego driver layers itself on top of the standard partition driver (if present) or on top of the disk driver. The cache routines are layered on top of the stego driver and the filesystem on top of the cache. Blocks in the cache are decrypted as they have passed through the oz_stego driver. When the cache wants to write, it writes to the oz_stego driver which encrypts the data and writes it to the disk.

How the data is formatted:

The first block of the partition was initially random data. The init command supplied the size you want the partition to be. Assuming a block size of 512:

All they can tell is, somewhere in that block are two numbers separated by an unknown number of longwords that when the block is decrypted, when XORd with two parts of the key hash, they give the size of the partition. Quite a task to break.

When you go to mount the partition, you give it the key, so it is easy for it to check to make sure you gave it the correct key as it looks in just the right spots of the first block.

The rest of the partition consists of standard encryptions of the data blocks. However, the blocks are rotated in the disk. So LBN 5 of the stego disk might be stored in block 25 of the partition, LBN 6 is stored in LBN 26, etc. The rotation factor is based on part of the key. This is done so an attacker can't tell where any known plaintext blocks are (like the home block or root directory). I wanted to do some interleave based on part of the key hash, but then transfers would only be done a block at a time and it doesn't add much more security.