aboutsummaryrefslogtreecommitdiff
path: root/mysql/extra/yassl/taocrypt/include/modes.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'mysql/extra/yassl/taocrypt/include/modes.hpp')
-rw-r--r--mysql/extra/yassl/taocrypt/include/modes.hpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/mysql/extra/yassl/taocrypt/include/modes.hpp b/mysql/extra/yassl/taocrypt/include/modes.hpp
new file mode 100644
index 0000000..bfe8c6e
--- /dev/null
+++ b/mysql/extra/yassl/taocrypt/include/modes.hpp
@@ -0,0 +1,154 @@
+/*
+ Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+/* modes.hpp provides ECB and CBC modes for block cipher encryption/decryption
+*/
+
+
+#ifndef TAO_CRYPT_MODES_HPP
+#define TAO_CRYPT_MODES_HPP
+
+#include "misc.hpp"
+
+namespace TaoCrypt {
+
+
+enum Mode { ECB, CBC };
+
+
+
+// BlockCipher abstraction
+template<CipherDir DIR, class T, Mode MODE>
+class BlockCipher {
+public:
+ BlockCipher() : cipher_(DIR, MODE) {}
+
+ void Process(byte* c, const byte* p, word32 sz)
+ { cipher_.Process(c, p, sz); }
+ void SetKey(const byte* k, word32 sz)
+ { cipher_.SetKey(k, sz, DIR); }
+ void SetKey(const byte* k, word32 sz, const byte* iv)
+ { cipher_.SetKey(k, sz, DIR); cipher_.SetIV(iv); }
+private:
+ T cipher_;
+
+ BlockCipher(const BlockCipher&); // hide copy
+ BlockCipher& operator=(const BlockCipher&); // and assign
+};
+
+
+// Mode Base for block ciphers, static size
+class Mode_BASE : public virtual_base {
+public:
+ enum { MaxBlockSz = 16 };
+
+ explicit Mode_BASE(int sz, CipherDir dir, Mode mode)
+ : blockSz_(sz), reg_(reinterpret_cast<byte*>(r_)),
+ tmp_(reinterpret_cast<byte*>(t_)), dir_(dir), mode_(mode)
+ {}
+ virtual ~Mode_BASE() {}
+
+ virtual void Process(byte*, const byte*, word32);
+
+ void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); }
+protected:
+ int blockSz_;
+ byte* reg_;
+ byte* tmp_;
+
+ word32 r_[MaxBlockSz / sizeof(word32)]; // align reg_ on word32
+ word32 t_[MaxBlockSz / sizeof(word32)]; // align tmp_ on word32
+
+ CipherDir dir_;
+ Mode mode_;
+
+ void ECB_Process(byte*, const byte*, word32);
+ void CBC_Encrypt(byte*, const byte*, word32);
+ void CBC_Decrypt(byte*, const byte*, word32);
+
+ Mode_BASE(const Mode_BASE&); // hide copy
+ Mode_BASE& operator=(const Mode_BASE&); // and assign
+
+private:
+ virtual void ProcessAndXorBlock(const byte*, const byte*, byte*) const = 0;
+};
+
+
+inline void Mode_BASE::Process(byte* out, const byte* in, word32 sz)
+{
+ if (mode_ == ECB)
+ ECB_Process(out, in, sz);
+ else if (mode_ == CBC) {
+ if (dir_ == ENCRYPTION)
+ CBC_Encrypt(out, in, sz);
+ else
+ CBC_Decrypt(out, in, sz);
+ }
+}
+
+
+// ECB Process blocks
+inline void Mode_BASE::ECB_Process(byte* out, const byte* in, word32 sz)
+{
+ word32 blocks = sz / blockSz_;
+
+ while (blocks--) {
+ ProcessAndXorBlock(in, 0, out);
+ out += blockSz_;
+ in += blockSz_;
+ }
+}
+
+
+// CBC Encrypt
+inline void Mode_BASE::CBC_Encrypt(byte* out, const byte* in, word32 sz)
+{
+ word32 blocks = sz / blockSz_;
+
+ while (blocks--) {
+ xorbuf(reg_, in, blockSz_);
+ ProcessAndXorBlock(reg_, 0, reg_);
+ memcpy(out, reg_, blockSz_);
+ out += blockSz_;
+ in += blockSz_;
+ }
+}
+
+
+// CBC Decrypt
+inline void Mode_BASE::CBC_Decrypt(byte* out, const byte* in, word32 sz)
+{
+ word32 blocks = sz / blockSz_;
+ byte hold[MaxBlockSz];
+
+ while (blocks--) {
+ memcpy(tmp_, in, blockSz_);
+ ProcessAndXorBlock(tmp_, 0, out);
+ xorbuf(out, reg_, blockSz_);
+ memcpy(hold, reg_, blockSz_); // swap reg_ and tmp_
+ memcpy(reg_, tmp_, blockSz_);
+ memcpy(tmp_, hold, blockSz_);
+ out += blockSz_;
+ in += blockSz_;
+ }
+}
+
+
+} // namespace
+
+#endif // TAO_CRYPT_MODES_HPP