Kuro5hin.org: technology and culture, from the trenches
create account | help/FAQ | contact | links | search | IRC | site news
[ Everything | Diaries | Technology | Science | Culture | Politics | Media | News | Internet | Op-Ed | Fiction | Meta | MLP ]
We need your support: buy an ad | premium membership

Crypto Snippets 1: Message Integrity and IAPM

By Paul Crowley in Technology
Mon Nov 13, 2000 at 03:39:28 PM EST
Tags: Security (all tags)

When you send an encrypted message, you don't want anyone but the intended recipient to be able to read it. But there's another requirement that's often overlooked: you don't want anyone to be able to tamper with it either. Intuitively, it seems as if tampering with an encrypted message should be impossible, but unless the encryption scheme includes specific protection against tampering, you may be able to achieve all sorts of evil things.

A new technique, developed by IBM, may allow us to protect our messages against tampering for little more than the cost of encryption - but only if they'll let us use it.

This started life as a diary entry but I was encouraged to post it as a story. If I get the energy, I might even write more than one of these, and try and put together some snippets that add up to an introduction to those parts of cryptology and data security that I understand.

Let's suppose you're writing a banking application. And suppose you encrypt with the One Time Pad, the only cipher proven secure. To make the illustration simpler, we'll pretend your message, and your key, consist entirely of decimal digits:

03 123 654 000123 
03 - a code meaning transfer (that I just made up)
123 - from account 123
654 - to account 654
000123 - the sum of $1.23

Now we encrypt with the one-time pad:

92364162348364 - the key
03123654000123 - the plaintext message
95487716348487 - ciphertext: digit-wise sum (ignore carry)

Of course I generated the key by banging on the keyboard, but a real one-time pad would be generated in a secure way and used only once.

Decryption is simple - just subtract.

95487716348487 - the ciphertext
92364162348364 - the key
03123654000123 - the plaintext: digit-wise subtraction (ignore carry)

This method is perfectly secure, literally, as far as confidentiality is concerned. But what about security against tampering?

It turns out that if you hold account 654, and you can tamper with this message in transit, you can change things very much to your advantage. Just add a 9 to the 6th digit from the end.

95487716348487 - ciphertext before tampering
00000000900000 - tamper string
95487716248487 - new ciphertext (digit-wise sum)

When we decrypt this tampered message, the plaintext is rather different:

95487716248487 - new ciphertext (digit-wise sum)
92364162348364 - the key
03123654900123 - the plaintext: digit-wise subtraction (ignore carry)

03 - transfer
123 - from account 123
654 - to account 654
900123 - the sum of $9001.23

What can you do? One solution might be to use digital signatures. If every message is signed with the private key of the sender, it's integrity will be preserved by the signature scheme. This works, but it's massive overkill: digital signatures are very slow to compute. In general, when you've got a shared secret with the other party, you want to use symmetric, secret key techniques rather than assymmetric, public key techniques, since they tend to be more efficient in every way. And the secret key equivalent of a digital signature is a Message Authentication Code, or a MAC.

A MAC is a very short (perhaps 64 bit) addenum to a message that verifies it hasn't been tampered with. To generate, or verify the MAC, you need the MAC secret. A randomly generated message will have only one chance in 2^64 of passing the MAC check. MACs are very like message digest functions (otherwise known as hash functions; MD5 and SHA are examples) except with a secret ingredient that you need to generate or verify the digest. Indeed, there are simple ways to use a function like SHA to make a MAC simply by sprinkling in a secret along with the data being hashed. If you need encryption and message integrity, just append a MAC to the message, then encrypt the whole thing.

But for some environments, like smart cards, you might find that the only cryptographic primitive you've got room for is the AES block cipher. NIST standardised on a block cipher because block ciphers are to cryptologists what towels are to hitch hikers - you can turn them to useful objects in pretty much any crypto situation. And it's pretty simple to MAC with a block cipher. Divide the message into blocks M_1 .. M_n; start with a start value unique to this message R, encrypt it with the block cipher to make X_0 = E(R), then make X_i = E(X_(i-1) XOR M_i), and use X_n as your MAC.

This kind of MAC is known as CBC-MAC - because it's exactly the same as CBC mode encryption, except that you throw away all but the last block when you've finished. This means that when you MAC and encrypt, you're effectively doing the work of encrypting the message twice. It's occured to quite a few people that there must be a way of doing the work only once, and getting both encryption and message integrity out of one block cipher pass over the message. But it's not as easy as it looks, and lots of attempts to solve the problem have been broken.

It now seems that the problem is solved. NIST put out a call to help create standard chaining modes to go along with the standard block cipher, and one of the submissions - by Charinjit S Jutla of IBM - proposes chaining modes (IACBC, IAPM) that give both encryption and integrity securly for little more than the cost of one alone. A flurry of new activity has resulted, and now there are several excellent chaining modes with this property.

Unfortunately, it seems likely that all of these techniques will be subject to a patent held by IBM. Unless NIST can persuade IBM to give the world a royalty-free license to these techniques in return for the credit of being the name behind a national standard, it seems we may be faced with a choice between giving IBM ownership of our protocols, or having our encryption run at half the speed we could.


Voxel dot net
o Managed Hosting
o VoxCAST Content Delivery
o Raw Infrastructure


Related Links
o diary entry
o Also by Paul Crowley

Display: Sort:
Crypto Snippets 1: Message Integrity and IAPM | 25 comments (25 topical, editorial, 0 hidden)
Ok... (4.00 / 1) (#1)
by pb on Mon Nov 13, 2000 at 02:55:08 PM EST

This is interesting, but I fail to see how account #654 would know which digit to change; this is a one-time pad, and hopefully all the data involved is secure, so they could definitely tamper with the message, but they wouldn't know what to change!

I'd expect at least a CRC of some sort to protect a message from tampering; you'd probably want to append it to the original message, and encrypt the whole thing. Chaining is even better, but I thought we'd had chained encryption modes for quite some time. It certainly isn't a new technique.

Don't get me wrong, it sounds like you're saying that the specific approach you're outlining is new, but I'm amazed this sort of thing hasn't been done before. Even a password-encrypted ZIP file had an internal CRC check on each file, to verify its integrity...

Also, I think there should be a rule like that for national standards, where patent-holders give their patents to a standards board, or waive their rights in exchange for some sort of benefits... That would solve a lot of problems with MPEG4, and other "standards" that companies might want to charge for after the fact... (like GIF files, bah.)
"See what the drooling, ravening, flesh-eating hordes^W^W^W^WKuro5hin.org readers have to say."
-- pwhysall
Security/Obscurity/Social Engineering (5.00 / 1) (#3)
by Parity on Mon Nov 13, 2000 at 03:31:38 PM EST

#654 knows what digit to change because s/he either read the open spec or bribed someone to reveal the closed spec for the transfer encoding, and s/he knows how much money is supposed to be transferred, so s/he simply picks a digit high enough to be sure it's being added to 0. Or, in other words, #654 may or may not know, but to presume that s/he doesn't is to rely on security-by-obscurity and weaken the security by strong cryptography.

As for the CRC, that was covered in the middle, using MD5 and SHA as examples, but you could substitute 'CRC' and it would have the same meaning. Besides, CRC is a lousy authentication check; if you can tamper the data you can tamper the CRC to make it match.

Parity Space

[ Parent ]
Tampering with the CRC... (5.00 / 1) (#4)
by pb on Mon Nov 13, 2000 at 03:47:29 PM EST

Well, of course, you could tamper with the whole message, <B>provided you can decrypt it first</B>. Heck, you could intercept the message and send one of your own. I agree that it's nicer to have an encryption method that scrambles everything after the tampering takes place, but if your encryption method isn't secure in the first place, you've got much bigger problems than worrying about CRC-checking or not.

And no, assuming that someone doesn't know the contents of an encrypted message isn't relying on security through obscurity. It's a pretty reasonable assumption, provided you have a good encryption method and you don't go around saying stuff like "The password is Armageddon!" when it actually is...
"See what the drooling, ravening, flesh-eating hordes^W^W^W^WKuro5hin.org readers have to say."
-- pwhysall
[ Parent ]
*sigh* (4.00 / 2) (#5)
by Parity on Mon Nov 13, 2000 at 04:06:53 PM EST

And no, assuming that someone doesn't know the contents of an encrypted message isn't relying on security through obscurity. It's a pretty reasonable assumption, provided you have a good encryption method and you don't go around saying stuff like "The password is Armageddon!" when it actually is..

In -general- assuming someone doesn't know the contents of an encrypted message is reasonable, in the specific case of preventing tampering with bank transfers this is -not- reasonable. The would-be thieves will know the format of the standardized transfer encoding, and the method of encryption (but not the one-time pad), and they will know how much money is being transferred from what account, to what account, at what time. Maybe the get an accomplice to initiate the transfer, someone authorized to make small transfer but not large ones, and then tamper it en-route, or maybe they use a regular monthly or weekly payment that they can predict, but they'll get the information about a transfer, or engineer one to their specifications. Maybe they attack account numbers instead of or in addition to the monetary value, and simply wire -themselves- money, but change the 'from' account number en-route.

Yes, this is a difficult scenario to pull off, but it's not impossible, and it's the kind of scenario the technique described in the article can prevent.

As for CRC, you wouldn't need to decrypt the CRC value to change it, you'd just need to know where it was stored and calculate the change... 'if we increase this, then these bits here would change' and add the appropriate compensation in, the same way the money above was increased without decrypting the message.
Parity None

[ Parent ]
Example... (3.00 / 1) (#7)
by pb on Mon Nov 13, 2000 at 04:56:21 PM EST

Ok, I see your point, as it relates to the example, but with a traditional one-time pad, ("truly random data combined with the plaintext", usually XOR) you wouldn't know what you were changing. Changing even the least significant byte in a word might still end up lowering the number. (not in this scenario, though, 'cause it's pretty broken)

It would be very clever, however, if you could tamper with an encrypted message, and make all of its internal checks come out right. However, you'd likely destroy the message (or at least some of the data) in the process.

But don't we already have secure block ciphers that we can use in CBC mode, or are they *all* too slow?
"See what the drooling, ravening, flesh-eating hordes^W^W^W^WKuro5hin.org readers have to say."
-- pwhysall
[ Parent ]
CBC mode does not guarantee message integrity (5.00 / 1) (#11)
by Paul Crowley on Mon Nov 13, 2000 at 07:26:28 PM EST

Block ciphers are not all too slow. Rijndael (AES) is just fine for speed, for example. But CBC mode should not be considered to offer any kind of message integrity. I don't understand the attacks well enough to explain them here, but there are attacks. Use a separate MAC.

It's worth noting that in my example you don't have to guess the content of the message particularly well. Most amounts transferred will be much smaller than the amount field, so if you can just scramble the amount field you're likely to get a larger amount of money. And you don't care if the "from" account is scrambled too -who cares whose money you get? And it's also not a problem if your chances of defeating the integrity check is one in a million, if you can tamper with a million messages which might not be implausible in some circumstances.

But the application protocol is not broken - the cryptosystem is. It's not the job of application designers to make their message formats crypto friendly - it's the job of cryptographers to guarantee message confidentiality and integrity no matter what the content. And in general, it's a job that cryptographers can do rather well, so putting a burden on application designers to help the cryptographers out would be crazy.

Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Integrity checks... (2.00 / 1) (#13)
by ucblockhead on Tue Nov 14, 2000 at 12:09:29 AM EST

If the integrity checks are 1 in a million, isn't someone going to clue in that an attack is taking place long before the attacker gets lucky and succeeds?
This is k5. We're all tools - duxup
[ Parent ]
Depends on the circumstances (4.00 / 1) (#15)
by Paul Crowley on Tue Nov 14, 2000 at 04:04:47 AM EST

For example, supposing you try sending 1000 faked messages to each of 1000 different sites? Each site might be able to accept 100 messages a second, so you could complete the distributed attack in ten seconds.

There's no reason to muck about with probabilities as favourable to the attacker as this when we can easily reduce the odds to 1 in 2^64 with a 64-bit MAC.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Banks... (3.00 / 1) (#17)
by ucblockhead on Tue Nov 14, 2000 at 11:41:54 AM EST

These are bank transactions... I'd suspect that sending 100 messages a second, most directed at one target account number, would trigger all sorts of alarms in any well-designed system.

Credit card companies already employ all sorts of software to detect "unusual use".
This is k5. We're all tools - duxup
[ Parent ]
That's no excuse to deploy weak crypto. (4.00 / 1) (#18)
by Paul Crowley on Tue Nov 14, 2000 at 12:53:34 PM EST

It looks like I should write a longer article on the philosophy of cryptography. But in brief, it would be extremely bad practice to deploy a cryptographically weak integrity solution and hand the problem on to the designers of the rest of the application to catch. What should the application do when the alarms go off - shut down that account? That allows a new denial of service attack directed at specific accounts!

No, the crypto layer can and should promise strong integrity along with strong encryption. It's the Right Thing.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Shutting off account (4.00 / 1) (#19)
by ucblockhead on Tue Nov 14, 2000 at 01:37:41 PM EST

Credit Card agencies do indeed shut off the account temporarily when there is statistically "unusual" activity and attempt to contact the account holder directly.

I'm not suggesting that you shouldn't use good crypto, but I think it is a mistake to depend on crypto as the only security mechanism. In situations like this, I also think it is imperative to get human beings in the loop as soon as something unusual happens, just in case whatever technological security methods that you use fail.

In a banking application, you are going to have to have a lot of application level security anyway because you can't depend on all attacks coming from the outside. You are almost certainly going to want to do some sort of acknowledgement because your attacker might be someone "trusted" on the other side. You are almost certainly going to want to do some sort of statistical analysis for this same reason.

This is k5. We're all tools - duxup
[ Parent ]
Yes, it is security by obscurity. (4.00 / 1) (#10)
by Paul Crowley on Mon Nov 13, 2000 at 07:17:45 PM EST

If you're trying to build a secure system, you should in general assume that your attackers have excellent powers not only to guess the contents of messages, but also to force messages to have particular convenient content. With a strong cryptosystem, the attacker should be able to choose the contents of a trillion messages, know that message a trillion and one is one of "foo" or "bar", and have absolutely no way of making a better guess than chance of which it is. Nor should they be able to generate any valid message that they haven't already seen with probability better than chance.

We make these demands on cryptosystems because it's a big mistake to place a burden on the designers of applications to keep their messages unguessable. Lots of real cryptosytems have seen practical, usable breaks in which people really were able to force particular ciphertexts, or guess their contents. Crypto should *just work* - every time, all the time. You have enough to worry about with the rest of the system that trying to work around problems with the cryptosystem as well is too much to ask.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Make byte order random. (4.00 / 1) (#6)
by ucblockhead on Mon Nov 13, 2000 at 04:38:21 PM EST

If the message is short, you could prevent the attacker from knowing what byte to change by randomly shuffling the bytes and then putting a byte-map at the front of the message before encrypting telling the receiver what order the bytes should be put into once decrypted.

In this case, the attacker wouldn't know which byte was the crc either.
This is k5. We're all tools - duxup
[ Parent ]
Most quick fixes to crypto problems don't work. (5.00 / 1) (#9)
by Paul Crowley on Mon Nov 13, 2000 at 07:10:50 PM EST

When you see attacks on cryptosystems, it's tempting to think that the attack depends on such a fine balance of circumstances that the slightest modification will make it impossible. In fact, quick fixes to cryptosystems usually result in quick fixes to the attacks that keep them working.

Taking your proposal as an example, if the message is short the attacker might be able to vary some bytes at random and have a decent probability of getting an improvement in the amount transferred. If the result of getting it right is a million dollar win, it's got to be better than the lottery.

Building systems that can really give us strong guarantees about message integrity, like building secure ciphers, is *much* *much* harder than your intuition will tell you, and the guarantees demanded are far stronger than most people seem to realise they need. I don't plan to try and cryptanalyse every quick fix proposed here on Kuro5hin, but I've just dispensed with two (yours and CRCs) and I have the cryptanalytic skills of a brained ant compared to the really good people.

Proposing crypto systems is much easier than breaking them: proposing *good* crypto systems is at least as hard as breaking them and you're only really in a position to do it when you've broken a few.

In short: the crypto systems you've seen in this show were built by experts. Don't try this at home. Or at least, don't try this at home and then use it for any real application.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Acknowledgement transactions (4.00 / 1) (#14)
by ucblockhead on Tue Nov 14, 2000 at 01:47:21 AM EST

It would be pretty easy to stop an attacker who is using a "change random bytes and pray" attack if you simply sent an acknowledgement transaction back, encrypted with a different key, and didn't go forward with the transaction unless the acknowledgement matched the original. With this, the attacker would not only have to change "good" bytes, they'd have to manage to change the same data in the same way in two messages encrypted with different keys. I don't see how that could be done without decrypting the messages.

And just trying over and over until you "get lucky" could be easily prevented by keeping track of the number of acknowledgements that don't match.

In addition, changing random data is very likely to make the message fail sanity checks. Obviously if the amount gets changed to $2 billion, flags are going to be raised. And you can easily avoid the problem of a random change in the amount being an increase by simply making it a signed number and making the sign represent the direction of the transfer. Then any random change to the amount is 50% likely to withdraw the money out of the attackers account rather than put money into it. (This is assuming that you scramble at the bit level and not the byte level.)

The sanity checks are most important. If you suddenly find that you have thousands of messages that are to invalid accounts, or are to amounts that are too big, or with bad routing numbers, etc, etc, and 95% of them have the same target account number, you're going to look at that account very carefully. That's not what the attacker is going to want! So in general, you force to attacker to make a change that looks "normal". If they can't decrypt the message, that won't be possible.

This is k5. We're all tools - duxup
[ Parent ]
Why put such a burden on the application designer? (4.00 / 2) (#16)
by Paul Crowley on Tue Nov 14, 2000 at 04:14:18 AM EST

I don't see the advantage of making the people designing the application and the protocol jump through all these hoops when we have secure MACs that will stop the attacks I've outlined in their tracks. Believe me, designing a secure protocol is extraordinarily difficult even without the massive extra burden you propose. Why not just ensure message integrity at the same time as encryption?
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
CRCs and tampering (5.00 / 1) (#8)
by Paul Crowley on Mon Nov 13, 2000 at 06:56:11 PM EST

Intuitively, you would expect a CRC to work. In fact, a CRC will make this attack no harder, because CRCs are linear: CRC(A + B) = CRC(A) + CRC(B). Thus, if you want to flip a few individual bits, it's easy to work out which bits to flip.

Chaining is used because if you encrypted each block the same way and independently, you'd leak information: identical blocks of plaintext would result in identical blocks of ciphertext. In fact the IV should vary between messages so that even if the entire message is identical, this fact is kept from eavesdroppers. And yes, chaining is at least as old as DES itself.

It's very tempting to think that normal chaining modes like CBC or CFB should be able to do double duty as an integrity check, but there have been many attempts to make this work and many attacks which show imperfections in these schemes, and to think of these modes as providing any meaningful message integrity is wrong. These new chaining modes are the first to meet this hope.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Good news... (4.00 / 1) (#2)
by trhurler on Mon Nov 13, 2000 at 03:00:14 PM EST

IBM is not known for trying to screw over NIST. They invented DES, you know. But, even if they want to do so, they're going to find themselves at the receiving end of a lawsuit, because any and all materials submitted as part of the AES process must be freely reusable, and NIST has announced their intent to sue anyone who tries to go back on that well in advance of anyone submitting anything. Yes, IBM -could- try, but I doubt that they will be so foolish. I'm against the law in question(antitrust,) but at least in this case the rules are clear and easy to follow: if you don't want to give it away, don't give it to NIST.

'God dammit, your posts make me hard.' --LilDebbie

No, that only applied to the block cipher (4.50 / 2) (#12)
by Paul Crowley on Mon Nov 13, 2000 at 07:32:35 PM EST

That obligation only applied to the block cipher design process. IBM are currently saying that they would demand a license fee for this stuff. See the email comments on the modes of operation pages.

I do hold out every hope that they'll experience a change of heart, though.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Reconsider use of MACs where proof important (3.00 / 1) (#20)
by gbroiles on Tue Nov 14, 2000 at 08:33:26 PM EST

You might want to think carefully about using MACs instead of digital signatures - if there's a shared secret, both (or all) possessors of the secret might plausibly have generated the data over which the MAC was calculated.

If one party later needs to prove that the other was the originator of the data, a digital signature would at least tend to show that the other party - or someone who got access to their keying material - was the originator. The recipient, in a MAC-only environment, is an equally plausible source of the data in question.

Authentication is not non-repudiation (none / 0) (#21)
by Paul Crowley on Wed Nov 15, 2000 at 04:37:29 AM EST

Non-repudiation is a much trickier problem. The article only addresses authentication.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
Non-malleability? (3.00 / 1) (#22)
by jason on Thu Nov 16, 2000 at 10:21:06 PM EST

This seems similar to the concept of non-malleability. See the most recent paper defining it from the folks who first(?) considered it... These schemes aren't a part of cypher-block chaining, but if IBM claims an overly broad patent, these might provide prior art on some aspects.

There also seems to be a refinement already (OCB mode)... Would the refinement count as a patentable improvement? If so, would that annul the need to license the original?

Jason, who doesn't understand patenting mathematics...

Yes, this is non-malleability. (none / 0) (#23)
by Paul Crowley on Fri Nov 17, 2000 at 04:56:54 AM EST

As far as I understand it, this property is non-malleability. And yes, OCB mode is *really* neat. I haven't read the text of the patent (in fact, I don't even know the patent number) so I can't tell if it applies to OCB, but the way these things are drafted I'm not optimistic.
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
[ Parent ]
a couple points (none / 0) (#24)
by SEAL on Fri Nov 17, 2000 at 09:37:08 PM EST

First, the one-time pad is used as an example of the only proven secure encryption method. Let's clarify that as algorithmically secure. In real-world use, however, there's much more to security than just the algorithm. One reason public-key encryption is so important is because it doesn't require the author to transport his secret key over an insecure medium, whether that be physical or electronic. No, it hasn't been proven that there's no polynomial time attack on PGP (for example). But most would agree that this is MUCH less of a risk than getting a key intercepted in transit.

Second, the ability to change a portion of an encrypted message is very unlikely to result in a new message that is not corrupt. It's right up there with the possibility that someone will find a polynomial time crack to PGP. I've read the comments about CRCs and such. But what people are forgetting is compression. For those who didn't know, PGP performs both compression and encryption.

A simple change to the encrypted file would most likely result in a file that would not decrypt properly. If you were lucky or smart enough to avoid that, it would probably fail at the decompression stage, either resulting in garbage, or failing on the CRC.

My point here, is that IBM's decision to keep this technology proprietary or not is, for the most part, inconsequential. A good security solution should make the amount of effort from an attacker be greater than the rewards of success. I feel that when used properly, PGP and GPG achieve this goal. In the grand scheme of things, there's a greater chance that someone will break into my house and steal my secret key, than successfully tamper with one of my encrypted messages.

I'm not opposed to more R&D and improvements, but I'm not going to lose sleep if IBM decides to hang on to a few patents.

Best regards,


It's only after we've lost everything that we're free to do anything.
Not all of the modes are patented (none / 0) (#25)
by Paul Crowley on Thu Dec 14, 2000 at 01:57:02 PM EST

This note from Virgil Gligor, co-author of the XCBC and XECB modes, points out that these modes were published before IBM could make any claim to coverage from their patent, and so are patent-free. The note can be found in NIST's truly un-navigable Modes of Operation Forum. Yes, discussion finished here some time ago, but just for the record...
Paul Crowley aka ciphergoth. Crypto and sex politics. Diary.
Crypto Snippets 1: Message Integrity and IAPM | 25 comments (25 topical, 0 editorial, 0 hidden)
Display: Sort:


All trademarks and copyrights on this page are owned by their respective companies. The Rest 2000 - Present Kuro5hin.org Inc.
See our legalese page for copyright policies. Please also read our Privacy Policy.
Kuro5hin.org is powered by Free Software, including Apache, Perl, and Linux, The Scoop Engine that runs this site is freely available, under the terms of the GPL.
Need some help? Email help@kuro5hin.org.
My heart's the long stairs.

Powered by Scoop create account | help/FAQ | mission | links | search | IRC | YOU choose the stories!