/* Konton2.h */ /* Copyright (C) 2002, 2003, 2004 by J. David Sexton. All rights reserved. */ /* "Konton" is Japanese for "primordial chaos." It's pronounced "kone-tone." Konton2 is a stream cipher that encrypts byte-by-byte. It features feedback from the encryption and decryption functions so that different plaintexts encrypted with the same key are encrypted with different keystreams. KonSetCryptKey only needs to be called when the key is changed or initially set. The key can be any length from zero bytes to the limit of the size_t type. Before it returns, KonSetCryptKey calls KonInitCrypt; a call to KonInitCrypt immediately after a call to KonSetCryptKey is unnecessary but harmless. KonInitCrypt initializes the state data using the key set by KonSetCryptKey. KonInitCrypt is called before a set of data is encrypted or decrypted. KonIndexState initializes the state data using the key set by KonSetCryptKey and an index value. In indexed encryption and decryption, the data is processed in blocks with each block accompanied by its index value. KonIndexState is called with the index value before each block of data is encrypted or decrypted. After KonIndexState is called, KonInitCrypt must not be called. KonDoubleIndexState is just like KonIndexState, except that it uses two index values instead of one, thus squaring the number of blocks that can be index-encrypted with the same key. KonQuadrupleIndexState is just like KonIndexState, except that it uses four index values instead of one, thus raising to the fourth power the number of blocks that can be index-encrypted with the same key. KonCryptSynch encrypts and decrypts data without the feedback mentioned above; the keystream is unaffected by the plaintext. In this mode Konton2 runs as a synchronous stream cipher. This mode lacks the error propagation of Konton2's normal mode used by all the other encryption and decryption functions. KonEncryptData encrypts data with the feedback mentioned above. KonDecryptData decrypts data encrypted with KonEncryptData. KonEncryptASCII encrypts only those bytes with values > 31 and < 127, and it encrypts them into bytes with values > 31 and < 127. In other words, it encrypts ASCII text into ASCII text and leaves other bytes untouched. KonDecryptASCII decrypts text encrypted with KonEncryptASCII. KonEncryptText encrypts only those bytes with values > 31, and it encrypts them into bytes with values > 31. In other words, it encrypts text into text and leaves other bytes untouched. KonDecryptText decrypts text encrypted with KonEncryptText. KonZapCrypt zeros all of the state data. KonNextPRndNum is Konton2's PRNG. */ #ifndef Konton_H #define Konton_H #include#include "KonTyps2.h" void KonSetCryptKey (register KonEnvStruct *theEnv, const void *theKey, size_t keyLength); void KonInitCrypt (register KonEnvStruct *theEnv); void KonIndexState (register KonEnvStruct *theEnv, register Kon4ByteInt theIndex); void KonDoubleIndexState (register KonEnvStruct *theEnv, register Kon4ByteInt aIndex, register Kon4ByteInt bIndex); void KonQuadrupleIndexState (register KonEnvStruct *theEnv, register Kon4ByteInt aIndex, register Kon4ByteInt bIndex, register Kon4ByteInt cIndex, register Kon4ByteInt dIndex); void KonCryptSynch (register KonEnvStruct *theEnv, void *theData, size_t theLength); void KonEncryptData (register KonEnvStruct *theEnv, void *theData, size_t theLength); void KonDecryptData (register KonEnvStruct *theEnv, void *theData, size_t theLength); void KonEncryptASCII (register KonEnvStruct *theEnv, void *theData, size_t theLength); void KonDecryptASCII (register KonEnvStruct *theEnv, void *theData, size_t theLength); void KonEncryptText (register KonEnvStruct *theEnv, void *theData, size_t theLength); void KonDecryptText (register KonEnvStruct *theEnv, void *theData, size_t theLength); void KonZapCrypt (register KonEnvStruct *theEnv); Kon4ByteInt KonNextPRndNum (register KonEnvStruct *theEnv); #endif /* Here is some example code which shows how to call Konton2 functions. #include "Konton2.h" Prototype non-Konton2 functions. void OSHoldMemoryFunction (void *theBlock, size_t theLength); void OSUnholdMemoryFunction (void *theBlock, size_t theLength); void MyGetCryptKeyFunction (void *theKey, size_t theLength); void MyEraseKeyFunction (void *theKey, size_t theLength); void MySendOrStoreDataFunction (void *theData, size_t theLength); void MyReceiveOrRetrieveDataFunction (void *theData, size_t theLength); Declare the KonEnvStruct variable. KonEnvStruct gKonEnv; Now we're inside a function. Declare data blocks, the key, and the index for indexed encryption. unsigned char theData [kDataLength]; unsigned char otherData [kOtherDataLength]; unsigned char theKey [kMyKeyLength]; Kon4ByteInt theIndex; It's important that we don't allow the KonEnvStruct variable or the key to be written to the disk by OSes that use virtual memory. We really SHOULD follow the same rule for the plaintext to be encrypted. OSHoldMemoryFunction (&gKonEnv, sizeof (gKonEnv)); OSHoldMemoryFunction (theKey, sizeof (theKey)); Get and then set the key MyGetCryptKeyFunction (theKey, sizeof (theKey)); KonSetCryptKey (&gKonEnv, theKey, sizeof (theKey)); Erase the key, then we can unhold it. MyEraseKeyFunction (theKey, sizeof (theKey)); OSUnholdMemoryFunction (theKey, sizeof (theKey)); We don't have to call KonInitCrypt here because the last thing KonSetCryptKey does is call it. It wouldn't do any harm if we called it anyway. Encrypt some stuff. KonEncryptData (&gKonEnv, theData, sizeof (theData)); We're going to encrypt some other stuff with the same key, so this time we MUST call KonInitCrypt. KonInitCrypt (&gKonEnv); KonEncryptData (&gKonEnv, otherData, sizeof (otherData)); We're going to decrypt what we encrypted above, so we have to call KonInitCrypt again. KonInitCrypt (&gKonEnv); KonDecryptData (&gKonEnv, theData, sizeof (theData)); Now we'll do some indexed encryption and decryption. We'll assume that KonSetCryptKey has already been called. First we have to call KonIndexState with the index of the block. Note that after we call KonIndexState we DON'T call KonInitCrypt. KonIndexState (&gKonEnv, theIndex); Encrypt the data. KonEncryptData (&gKonEnv, theData, sizeof (theData)); Send (or store) the index and the data. MySendOrStoreDataFunction (&theIndex, sizeof (theIndex)); MySendOrStoreDataFunction (theData, sizeof (theData)); Now we'll do indexed decryption. Once again, we'll assume that KonSetCryptKey has already been called. Receive (or retrieve) the index and the data. MyReceiveOrRetrieveDataFunction (&theIndex, sizeof (theIndex)); MyReceiveOrRetrieveDataFunction (theData, sizeof (theData)); Call KonIndexState with the index of the block, but don't call KonInitCrypt. KonIndexState (&gKonEnv, theIndex); Decrypt the data. KonDecryptData (&gKonEnv, theData, sizeof (theData)); We're finished with all our encryption and decryption. Wipe our KonEnvStruct variable clean, then we can unhold it. KonZapCrypt (&gKonEnv); OSUnholdMemoryFunction (&gKonEnv, sizeof (gKonEnv)); */