MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
modes.hpp
1 /*
2  Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to the
15  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16  MA 02110-1301 USA.
17 */
18 
19 /* modes.hpp provides ECB and CBC modes for block cipher encryption/decryption
20 */
21 
22 
23 #ifndef TAO_CRYPT_MODES_HPP
24 #define TAO_CRYPT_MODES_HPP
25 
26 #include "misc.hpp"
27 
28 namespace TaoCrypt {
29 
30 
31 enum Mode { ECB, CBC };
32 
33 
34 
35 // BlockCipher abstraction
36 template<CipherDir DIR, class T, Mode MODE>
37 class BlockCipher {
38 public:
39  BlockCipher() : cipher_(DIR, MODE) {}
40 
41  void Process(byte* c, const byte* p, word32 sz)
42  { cipher_.Process(c, p, sz); }
43  void SetKey(const byte* k, word32 sz)
44  { cipher_.SetKey(k, sz, DIR); }
45  void SetKey(const byte* k, word32 sz, const byte* iv)
46  { cipher_.SetKey(k, sz, DIR); cipher_.SetIV(iv); }
47 private:
48  T cipher_;
49 
50  BlockCipher(const BlockCipher&); // hide copy
51  BlockCipher& operator=(const BlockCipher&); // and assign
52 };
53 
54 
55 // Mode Base for block ciphers, static size
56 class Mode_BASE : public virtual_base {
57 public:
58  enum { MaxBlockSz = 16 };
59 
60  explicit Mode_BASE(int sz, CipherDir dir, Mode mode)
61  : blockSz_(sz), reg_(reinterpret_cast<byte*>(r_)),
62  tmp_(reinterpret_cast<byte*>(t_)), dir_(dir), mode_(mode)
63  {}
64  virtual ~Mode_BASE() {}
65 
66  virtual void Process(byte*, const byte*, word32);
67 
68  void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); }
69 protected:
70  int blockSz_;
71  byte* reg_;
72  byte* tmp_;
73 
74  word32 r_[MaxBlockSz / sizeof(word32)]; // align reg_ on word32
75  word32 t_[MaxBlockSz / sizeof(word32)]; // align tmp_ on word32
76 
77  CipherDir dir_;
78  Mode mode_;
79 
80  void ECB_Process(byte*, const byte*, word32);
81  void CBC_Encrypt(byte*, const byte*, word32);
82  void CBC_Decrypt(byte*, const byte*, word32);
83 
84  Mode_BASE(const Mode_BASE&); // hide copy
85  Mode_BASE& operator=(const Mode_BASE&); // and assign
86 
87 private:
88  virtual void ProcessAndXorBlock(const byte*, const byte*, byte*) const = 0;
89 };
90 
91 
92 inline void Mode_BASE::Process(byte* out, const byte* in, word32 sz)
93 {
94  if (mode_ == ECB)
95  ECB_Process(out, in, sz);
96  else if (mode_ == CBC) {
97  if (dir_ == ENCRYPTION)
98  CBC_Encrypt(out, in, sz);
99  else
100  CBC_Decrypt(out, in, sz);
101  }
102 }
103 
104 
105 // ECB Process blocks
106 inline void Mode_BASE::ECB_Process(byte* out, const byte* in, word32 sz)
107 {
108  word32 blocks = sz / blockSz_;
109 
110  while (blocks--) {
111  ProcessAndXorBlock(in, 0, out);
112  out += blockSz_;
113  in += blockSz_;
114  }
115 }
116 
117 
118 // CBC Encrypt
119 inline void Mode_BASE::CBC_Encrypt(byte* out, const byte* in, word32 sz)
120 {
121  word32 blocks = sz / blockSz_;
122 
123  while (blocks--) {
124  xorbuf(reg_, in, blockSz_);
125  ProcessAndXorBlock(reg_, 0, reg_);
126  memcpy(out, reg_, blockSz_);
127  out += blockSz_;
128  in += blockSz_;
129  }
130 }
131 
132 
133 // CBC Decrypt
134 inline void Mode_BASE::CBC_Decrypt(byte* out, const byte* in, word32 sz)
135 {
136  word32 blocks = sz / blockSz_;
137  byte hold[MaxBlockSz];
138 
139  while (blocks--) {
140  memcpy(tmp_, in, blockSz_);
141  ProcessAndXorBlock(tmp_, 0, out);
142  xorbuf(out, reg_, blockSz_);
143  memcpy(hold, reg_, blockSz_); // swap reg_ and tmp_
144  memcpy(reg_, tmp_, blockSz_);
145  memcpy(tmp_, hold, blockSz_);
146  out += blockSz_;
147  in += blockSz_;
148  }
149 }
150 
151 
152 } // namespace
153 
154 #endif // TAO_CRYPT_MODES_HPP