| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /*
- Copyright (c) 2009-2010 Christopher A. Taylor. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of LibCat nor the names of its contributors may be used
- to endorse or promote products derived from this software without
- specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- The ChaCha cipher is a symmetric stream cipher based on Salsa20.
- http://cr.yp.to/chacha.html
- */
- #ifndef CAT_CHACHA_HPP
- #define CAT_CHACHA_HPP
- #include <cat/Platform.hpp>
- namespace cat {
- /*
- To initialize the ChaCha cipher, you must specify a 256-bit key.
- Code example:
- ChaChaKey cck;
- char key[32]; // fill key here
- cck.Key(key, sizeof(key));
- Before each encryption or decryption with the ChaCha cipher,
- a 64-bit Initialization Vector (IV) must be specified. Every
- time a message is encrypted, the IV must be incremented by 1.
- The IV is then sent along with the encrypted message.
- Encryption code example:
- char message[19], ciphertext[19]; // message filled here
- u64 iv = 125125;
- u64 message_iv = iv;
- iv = iv + 1;
- ChaChaOutput cco(cck, message_iv);
- cco.Crypt(message, ciphertext, sizeof(ciphertext));
- Decryption code example:
- char ciphertext[19], decrypted[19]; // ciphertext filled here
- ChaChaOutput cco(cck, message_iv);
- cco.Crypt(ciphertext, decrypted, sizeof(decrypted));
- Sending all 8 bytes of the IV in every packet is not necessary.
- Instead, only a few of the low bits of the IV need to be sent,
- if the IV is incremented by 1 each time.
- How many? It depends on how many messages can get lost.
- If < 32768 messages can get lost in a row, then CAT_IV_BITS = 16 (default)
- I have provided a function to handle rollover/rollunder of the IV,
- which also works if the same IV is sent twice for some reason.
- It needs to know how many of the low bits are sent across, so be sure
- to change CAT_IV_BITS in this header if you send more or less than 16.
- Code example:
- u64 last_accepted_iv;
- u32 new_iv_low_bits;
- u64 new_iv = ChaCha::ReconstructIV(last_accepted_iv, new_iv_low_bits);
- -------------------------READ THIS BEFORE USING--------------------------
- Never use the same IV twice.
- Otherwise: An attacker can recover the plaintext without the key.
- Never use the same key twice.
- Otherwise: An attacker can recover the plaintext without the key.
- If you have two hosts talking to eachother securely with ChaCha encryption,
- then be sure that each host is encrypting with a DIFFERENT key.
- Otherwise: An attacker can recover the plaintext without the key.
- Remember that an attacker can impersonate the remote computer, so be
- sure not to accept the new IV until the message authentication code has
- been verified if your protocol uses a message authentication code (MAC).
- Otherwise: An attacker could desynchronize the IVs.
- */
- //// ChaChaKey
- class CAT_EXPORT ChaChaKey
- {
- friend class ChaChaOutput;
- u32 state[16];
- public:
- ~ChaChaKey();
- // Key up to 384 bits
- void Set(const void *key, int bytes);
- };
- //// ChaChaOutput
- class CAT_EXPORT ChaChaOutput
- {
- u32 state[16];
- void GenerateKeyStream(u32 *out);
- public:
- ChaChaOutput(const ChaChaKey &key, u64 iv);
- ~ChaChaOutput();
- // Message with any number of bytes
- void Crypt(const void *in, void *out, int bytes);
- };
- } // namespace cat
- #endif // CAT_CHACHA_HPP
|