Mercurial > public > ostc_companion
view AES/rijndael.h @ 3:4ace58a7c03c
Send disconnect command before closing the connection
The old BT module transmitted a notification in case a connection were
closed which cause the ostc to exit the uart loop. The new one doesn't
do this => send disconnect command to avoid waiting in the installation
loop till timeout or button press.
| author | Ideenmodellierer |
|---|---|
| date | Fri, 28 Nov 2025 20:00:02 +0100 |
| parents | 0b3630a29ad8 |
| children |
line wrap: on
line source
////////////////////////////////////////////////////////////////////////////// /// \file rijndael.h /// \brief Public Domain AES encryption/decryption /// \author Philip J. Erdelsky <pje@efgh.com>, JD Gascuel, and others. /// /// \copyright (c) 2015 JD Gascuel. All rights reserved. /// $Id$ ////////////////////////////////////////////////////////////////////////////// // // BSD 2-Clause License: // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. 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. // // 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. // ////////////////////////////////////////////////////////////////////////////// // HISTORY // 2002-09-03 PJE: original source http://www.efgh.com/software/rijndael.htm // 2015-03-14 jDG: Import into OSTC_Companion, major C++ rewrites to insure // key length is not messed up. Added ECb and CFB modes. #ifndef RIJNDAEL_H #define RIJNDAEL_H namespace Rijndael { #define KEYLENGTH(keybits) ((keybits)/8) #define RKLENGTH(keybits) ((keybits)/8+28) #define NROUNDS(keybits) ((keybits)/32+6) typedef unsigned long Word32; typedef unsigned char Byte; typedef Byte Block[16]; ////////////////////////////////////////////////////////////////////////////// /// \brief Public Domain AES encryption/decryption rewritten. /// /// The Rijndael encryption algorithm has been designed to replace the aging /// DES algorithm. Like DES, it is a block cipher. It uses 128-bit, 192-bit /// or 256-bit keys. This implementation encrypts 128-bit blocks. /// (DES used 56-bit keys and 64-bit blocks.) /// /// The code in this package is a modified version of an implementation /// placed in the public domain by the following persons: /// + Vincent Rijmen vincent.rijmen@esat.kuleuven.ac.be /// + Antoon Bosselaers antoon.bosselaers@esat.kuleuven.ac.be /// + Paulo Barreto paulo.barreto@terra.com.br /// /// See details in http://www.efgh.com/software/rijndael.htm /// struct AES { static void setupEncrypt(Word32* rk, const Byte *key, int keybits); static void setupDecrypt(Word32* rk, const Byte *key, int keybits); static void encrypt(Word32 *rk, int nrounds, const Block plaintext, Block ciphertext); static void decrypt(Word32 *rk, int nrounds, const Block ciphertext, Block plaintext); static Word32 get_random(Word32 *rk, int keybits); }; ////////////////////////////////////////////////////////////////////////////// template<int keybits> class ECB : private AES { /// \brief Internal state /// /// storage for encryption buffer, required space: /// keybits 32-bit words required /// 128 44 /// 192 52 /// 256 60 /// \sa RKLENGTH macro. Word32 rk[RKLENGTH(keybits)]; public: typedef Byte Key[KEYLENGTH(keybits)]; ECB(); //------------------------------------------------------------------------ /// \brief Initialize encryption state /// /// /// \param[in] key: AES key, where length is: /// keybits number of bytes /// 128 16 /// 192 24 /// 256 32 /// \sa KEYLENGTH macro. /// /// \code /// Rijndael::ECB<128>::Key key = "my big secret"; /// Rijndael::ECB<128> enc; /// enc.setupEncrypt(key); /// ... /// Rijndael::Block plain = "Hello World!"; /// Rijndael::Block result; /// enc.encrypt(plain, result); /// \endcode void setupEncrypt(const Key key); //------------------------------------------------------------------------ /// \brief Encrypt a block of 16 bytes. /// /// \param[in] plaintext: The 16 bytes block to encrypt. /// \param[out] ciphertext: Space to store the 16 bytes of encrypted data. /// void encrypt(const Block plaintext, Block ciphertext); //------------------------------------------------------------------------ /// \brief Initialize decryption state. /// /// \param[in] key: AES key, where length is: /// keybits number of bytes /// 128 16 /// 192 24 /// 256 32 /// \sa KEYLENGTH macro. /// /// \code /// Rijndael::ECB<128>::Key key = "my big secret"; /// Rijndael::ECB<128> dec; /// dec.setupDecrypt(key); /// ... /// Rijndael::Block cipher = ...; /// Rijndael::Block result; /// Rijndael::decrypt(cipher, result); /// \endcode void setupDecrypt(const Key key); //------------------------------------------------------------------------ /// \brief Decrypt a block of 16 bytes. /// /// \param[in] ciphertext: The 16 bytes block of data to decrypt. /// \param[out] plaintext: Space to store the 16 bytes result block. /// void decrypt(const Block ciphertext, Block plaintext); //---------------------------------------------------------------------------- /// \brief Crypto base PRNG /// /// Based on wall-clock value and current key, but should be a crypto-secure /// generator. Word32 get_random(); }; ////////////////////////////////////////////////////////////////////////////// template<int keybits> class CFB : public ECB<keybits> { /// Initialization vector (salt), updated in CFB mode /// for the next block of text. Block iv; public: typedef Byte Key[KEYLENGTH(keybits)]; typedef Block IV; //------------------------------------------------------------------------ /// \brief Initialize encryption/decription state /// /// /// \param[in] key: AES key, where length is: /// keybits number of bytes /// 128 16 /// 192 24 /// 256 32 /// \sa KEYLENGTH macro. /// \param[in] iv: initialization vector. Some randomness needed to /// enforce the sequence is non replayable. /// /// \code /// Rijndael::CFB<128>::Key key = "my big secret"; /// Rijndael::CFB<128> enc(key, iv); /// ... /// Rijndael::Block plain = "Hello World!"; /// Rijndael::Block cipher, again; /// enc.encrypt(plain, cipher); /// enc.decrypt(cipher, again); /// \endcode CFB(const Key key, const IV iv); //------------------------------------------------------------------------ /// \brief Encrypt a block of 16 bytes, with IV (CFB mode) /// /// \param[in] plaintext: The 16 bytes block to encrypt. /// \param[out] ciphertext: Space to store the 16 bytes of encrypted data. /// void encrypt(const Block plaintext, Block ciphertext); //---------------------------------------------------------------------------- /// \brief Decrypt a block of 16 bytes, with IV (CFB mode) /// /// \param[in] ciphertext: The 16 bytes block of data to decrypt. /// \param[out] plaintext: Space to store the 16 bytes result block. /// void decrypt(const Block ciphertext, Block plaintext); }; ////////////////////////////////////////////////////////////////////////////// template<int keybits> ECB<keybits>::ECB() { for(int i=0; i<RKLENGTH(keybits); ++i) rk[i] = 0; } template<int keybits> void ECB<keybits>::setupEncrypt(const Key key) { AES::setupEncrypt(rk, key, keybits); } template<int keybits> void ECB<keybits>::encrypt(const Block plaintext, Block ciphertext) { AES::encrypt(rk, NROUNDS(keybits), plaintext, ciphertext); } ////////////////////////////////////////////////////////////////////////////// template<int keybits> void ECB<keybits>::setupDecrypt(const Key key) { AES::setupDecrypt(rk, key, keybits); } template<int keybits> void ECB<keybits>::decrypt(const Block ciphertext, Block plaintext) { AES::decrypt(rk, NROUNDS(keybits), ciphertext, plaintext); } ////////////////////////////////////////////////////////////////////////////// template<int keybits> Word32 ECB<keybits>::get_random() { return AES::get_random(rk, keybits); } ////////////////////////////////////////////////////////////////////////////// template<int keybits> CFB<keybits>::CFB(const Key key, const IV _iv) { ECB<keybits>::setupEncrypt(key); for(int i=0; i<16; ++i) iv[i] = _iv[i]; } template<int keybits> void CFB<keybits>::encrypt(const Block plaintext, Block ciphertext) { Block tmp; ECB<keybits>::encrypt(iv, tmp); for(int i=0; i<16; ++i) { ciphertext[i] = plaintext[i] ^ tmp[i]; iv[i] = ciphertext[i]; } } template<int keybits> void CFB<keybits>::decrypt(const Block ciphertext, Block plaintext) { Block tmp; ECB<keybits>::encrypt(iv, tmp); for(int i=0; i<16; ++i) { plaintext[i] = ciphertext[i] ^ tmp[i]; iv[i] = ciphertext[i]; } } } #endif // RIJNDAEL_H
